diff --git a/Arm Designer/Arm Designer.vcxproj b/Arm Designer/Arm Designer.vcxproj
index 3b77fc107a02681529e61152d34cbc00d7061fd8..3ae37c20b525b105046483ae6f911a2aeef2cc27 100644
--- a/Arm Designer/Arm Designer.vcxproj	
+++ b/Arm Designer/Arm Designer.vcxproj	
@@ -161,6 +161,7 @@
     <ClInclude Include="..\include\segments.hpp" />
     <ClInclude Include="..\include\shader.hpp" />
     <ClInclude Include="..\include\stb_image.h" />
+    <ClInclude Include="..\include\utility.hpp" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\src\arm_designer.cpp" />
diff --git a/Arm Designer/Arm Designer.vcxproj.filters b/Arm Designer/Arm Designer.vcxproj.filters
index a4c131a83591e9c344ea6531e8807ebb1f2db6d6..8db2285a9670d5df28498a0813222d7dba9d5ecd 100644
--- a/Arm Designer/Arm Designer.vcxproj.filters	
+++ b/Arm Designer/Arm Designer.vcxproj.filters	
@@ -54,6 +54,9 @@
     <ClInclude Include="..\include\render_parameters.hpp">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\include\utility.hpp">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\src\glad.c">
diff --git a/include/arm_designer.hpp b/include/arm_designer.hpp
index 586a9d613790df067a494413fb964f922ce785af..5f3aa1605d123515a0c6b43ef80beb4e0a6ca9c1 100644
--- a/include/arm_designer.hpp
+++ b/include/arm_designer.hpp
@@ -12,7 +12,7 @@
 
 /*Window Resolution*/
 #define WIDTH 1280
-#define HEIGHT 720
+#define HEIGHT 1280
 /*Debugging: Get VRAM info*/
 #define GL_GPU_MEM_INFO_TOTAL_AVAILABLE_MEM_NVX 0x9048
 #define GL_GPU_MEM_INFO_CURRENT_AVAILABLE_MEM_NVX 0x9049
@@ -30,6 +30,8 @@ private:
 	/*Managers*/
 	Infrastructure infra_;
 	Segments segments_;
+	std::vector<bool> segments_shown_;
+	std::vector<int> segments_repetitions_;
 	//UndoOps undo_ops_;
 	/*Parameter Containers*/
 	RenderParameters render_params_;
@@ -57,4 +59,7 @@ private:
 
 	/*INPUT handle*/
 	bool input_handle_();
+
+	/*RESET view*/
+	void reset_view_();
 };
\ No newline at end of file
diff --git a/include/gui_parameters.hpp b/include/gui_parameters.hpp
index 87a0a0ec0dfb91ff4d511014809e53b9de55cf03..e23bdf7117c2005835b173ff0220e5c9073e04cb 100644
--- a/include/gui_parameters.hpp
+++ b/include/gui_parameters.hpp
@@ -1,8 +1,23 @@
 #pragma once
 #include <string>
 
+enum class SEL_MODE{NONE=0, NODE, LINE, SEGMENT};
+
 struct GuiParameters {
 	/*Path from which the next segment is loaded*/
 	char segment_load_path[128];
 	char segment_save_path[128];
+
+	/*Enable / Disable parameters*/
+	bool enable_drum_contour;
+
+	/*Mouse Selection Mode*/
+	SEL_MODE selection_mode = SEL_MODE::NONE;
+
+	/*Closest Object*/
+	float mindist_en = false;
+	float mindist_dist;
+	float mindist_seg_i;
+	float mindist_node_i;
+	float mindist_node_i2; //used when selecting lines
 };
\ No newline at end of file
diff --git a/include/render_parameters.hpp b/include/render_parameters.hpp
index 7d1ba05120731db76011588b008987d187605701..6c0cef92de069674c69219d57f0ea883c2660197 100644
--- a/include/render_parameters.hpp
+++ b/include/render_parameters.hpp
@@ -4,9 +4,29 @@
 #include <shader.hpp>
 
 struct RenderParameters {
+	glm::vec2 offset;
+	float zoffset;
+	float fov;
+
 	GLuint vbo_segment_nodes;
 	GLuint vao_segment_nodes;
 	Shader shader_segment_lines;
+	glm::vec3 color_segment_lines;
+	glm::vec3 color_segment_points;
+	glm::vec3 color_segment_rep_lines;
+	glm::vec3 color_segment_rep_points;
+	glm::vec3 color_segment_sel_lines;
+	glm::vec3 color_segment_sel_points;
+
+	std::vector<float> grid_coords;
+	GLuint vbo_grid_nodes;
+	GLuint vao_grid_nodes;
+	glm::vec3 color_grid_lines;
+
+	std::vector<float> drum_coords;
+	GLuint vbo_drum_nodes;
+	GLuint vao_drum_nodes;
+	glm::vec3 color_drum_lines;
 
 	std::string resource_path;
 };
\ No newline at end of file
diff --git a/include/segments.hpp b/include/segments.hpp
index 46f6582b3fcd83fb59d77fdf5fc5eec943e77f38..7299ce4f11db21c4e8b3f1b98aba489fab165e93 100644
--- a/include/segments.hpp
+++ b/include/segments.hpp
@@ -11,6 +11,7 @@ public:
 	bool save(std::string filename) const;
 	void clear();
 	const std::vector<Segment>& get_segments();
+	size_t size() const;
 
 private:
 	std::vector<Segment> segms_;
diff --git a/include/utility.hpp b/include/utility.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..ac0b44bf59fd7df4fce37f4afb120d6b7ee8aa99
--- /dev/null
+++ b/include/utility.hpp
@@ -0,0 +1,6 @@
+#pragma once
+#include <cmath>
+
+float distance(float x0, float y0, float x1, float y1) {
+	return std::sqrt((x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1));
+}
\ No newline at end of file
diff --git a/notebooks/DrumContour.ipynb b/notebooks/DrumContour.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..6c371c0666568eb4d5c512e64ed013f5c3c4076c
--- /dev/null
+++ b/notebooks/DrumContour.ipynb
@@ -0,0 +1,96225 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import struct\n",
+    "import numpy as np\n",
+    "import scipy.signal as sgn\n",
+    "import matplotlib.pyplot as plt\n",
+    "import math"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "%matplotlib inline"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "class Vertex:\n",
+    "    def __init__(self, stlfile):\n",
+    "        self.coords = struct.unpack('fff', stlfile.read(12))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "class Triangle:\n",
+    "    def __init__(self, stlfile):\n",
+    "        normal = Vertex(stlfile)\n",
+    "        self.vertices = [Vertex(stlfile), Vertex(stlfile), Vertex(stlfile)]\n",
+    "        dummydata = struct.unpack('h', stlfile.read(2))\n",
+    "        self.vertices.sort(key = lambda vertex: vertex.coords[2])\n",
+    "    def zCenter(self):\n",
+    "        return np.mean([self.vertices[0].coords[2], self.vertices[1].coords[2], self.vertices[2].coords[2]]);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Number of triangles (7208,)\n"
+     ]
+    }
+   ],
+   "source": [
+    "triangles = [];\n",
+    "with open(\"singlehole.stl\", \"rb\") as stlfile:\n",
+    "    header = stlfile.read(80);\n",
+    "    numtriangles = struct.unpack('i', stlfile.read(4))\n",
+    "    print(f'Number of triangles {numtriangles}')\n",
+    "    for i in range(numtriangles[0]):\n",
+    "        triangles.append(Triangle(stlfile))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "xCoords = [];\n",
+    "yCoords = [];\n",
+    "zCenters = []\n",
+    "for triangle in triangles:\n",
+    "    zCenters.append(triangle.zCenter())\n",
+    "    for i in range(3):\n",
+    "        xCoords.append(triangle.vertices[i].coords[0])\n",
+    "        yCoords.append(triangle.vertices[i].coords[1])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5e76b8850>]"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "plt.plot(xCoords, yCoords,'x')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5e77c7e20>]"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "plt.plot(sorted(zCenters),'x')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "selectedTriangles = []\n",
+    "for triangle in triangles:\n",
+    "    if (triangle.zCenter() > 0.0001) and triangle.zCenter() < 0.0002:\n",
+    "        selectedTriangles.append(triangle)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "boundaryLocations = [];\n",
+    "for triangle in selectedTriangles:\n",
+    "    boundaryLocations.append(triangle.vertices[2].coords)\n",
+    "boundaryLocations = list(np.unique(boundaryLocations, axis=0))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5e9c49eb0>]"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYAAAAD4CAYAAADlwTGnAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8/fFQqAAAACXBIWXMAAAsTAAALEwEAmpwYAAA7y0lEQVR4nO29f3xU5b3g//5MCKItUEpSYAI0ZgIiYDQQkFdqCqUW9KIt6L1Xi6UXdBFpeXG/0t7dlu7d1267l97udy/u5WtfiBThKy5Xu72GVVOFVZoUzQVJOhABIWRSKkmAJmgDVdGQefaPOedwZjJJJiST+fV5v155JfOcMyfPnHnO83mez08xxqAoiqJkHp5Ed0BRFEVJDCoAFEVRMhQVAIqiKBmKCgBFUZQMRQWAoihKhjIk0R3oCzk5OSY/Pz/R3VAURUkpamtr24wxuZHtKSUA8vPzqampSXQ3FEVRUgoR+UO0dlUBKYqiZCgqABRFUTIUFQCKoigZigoARVGUDEUFgKIoSoaiAkBRFIenqgJUB9rC2qoDbTxVFUhQj5R4ogJAUTIc96RfNH4ka3b52bo/4LSv2eWnaPzIBPdSiQcqABQlw7En/epAG6W+HFbPK2BDxQlOnrvEml1+nlxaTKkvJ9HdVOKACgBFySCiqXgAFk4bw5pdfjbuPcnmykYWF+dR7m/mW7dPpK6pXdVCaYoKAEXJINyrfcBR8dx7q5dv3T6RTfsamDs5h6r6VtbOL+S5g++R5SHqe1QtlPqkVCoIRVH6zlNVAYrGj6TUl0OpL4cnlxazamctt+SN5MS5Szy5tBiA5w6+x5JiL7v9LaxfNIWVZT7m+EazZpef1fMKWLPLz7dun8hzB99TtVCaoDsARUlzIlf9AB2dQaoDF/jW7RMBHF3/TWNHsH7RFDZXNjo2gSeXFtMZhJvHDmfTvga+dftEZ/JXVVBqozsARUlz7EncXsFvrz5NdpaHR8sKeO7ge7T++RNnRW9P7NO8I6lrag9r+/lvGhiW7WF79Wnm+EYDVwWHkpqoAFCUNMSt9oGQEJg7OZdN+0KT+DPLZ1Hqy3FUPPfe6g17v3vit3X+W5bNBGDVzloe3nGI7CwPW5bNVFVQCqMqIEVJQyLVPlv3B9jtb2aadwTZWVcfe3t3UNfU3u216praw3YIK0rzudwRZOLnbwib/FUdlHqoAFCUNMSt9nn8BT8bKk6wftEUKtaWsWXZzDDhUOrL4bG5vm6v9dhcX9huwDYWH2+5yNb9AaddPYNSD1UBKUoaEenxY7t2TvOOYGVZaJJ3r/r7or6xJ3l7NzDVO4INFSc43nKJqvpW9QxKQXQHoChphFv1Ux1oY3v1aYZle3jv/Y/CvIB6W/VHw60KAlhZ5mOqd4QTMKaeQamH7gAUJY1w+/l3dAbJzgoZfIF+p3WIFBjVgTbee/8j9QxKYVQAKEqaUerLoShvJG8FLvBoWYEz4V+L2qc7onkGfXvb22RnCdssDyP7vLqm9j7vNpTBISYVkIjcJSInRaRBRH7Qw3n3i4gRkRLr9UMictj1ExSR26xjldY17WNfGJBPpCgZTnWgjXfPXXJSOcRq7O0L0TyDrgQNHZ0mrB9qGE5uxBjT8wkiWUA98DWgCTgEfNMYczzivOFABTAUWGOMqYk4fguw2xjjs15XAt+PPK8nSkpKTE1NzKcrSsYRaaiNfB3P/2kHmQGsKM3XlBFJhIjUGmNKIttj2QHMBhqMMY3GmE+B54FvRDnvJ8DPgMvdXOeb1nsVRYkTkYbaWPz8+4NbwKxbcBNbls3k4087NWVEihCLAMgDzrheN1ltDiIyA5hgjKno4ToPAP8S0bbdUv/8vYhItDeJyKMiUiMiNa2trTF0V1Eyg2ipnYvGj+wy2Q+k6ieSSIEDkJ0lDPEI26tPO95IqgpKTvrtBioiHmAj8L0ezrkd+MgYc9TV/JAx5hagzPpZFu29xpinjTElxpiS3Nzc/nZXUdKG7lI7D+ZEGxkktmaXn23LZ/HsI7MBeHjHIVbtrFVVUJISiwBoBia4Xo+32myGA9OBShE5DcwBXrINwRYPErH6N8Y0W78vAbsIqZoURYkRd7Tvxr0nE169S1NGpB6xCIBDwCQRuVFEhhKazF+yDxpj2o0xOcaYfGNMPnAA+Lpt3LV2CH+NS/8vIkNEJMf6Oxu4B3DvDhRF6Qa36scd7Ttl7PCErrI1ZUTq0WscgDHmioisAfYAWcAzxphjIvJjoMYY81LPV+DLwBljTKOr7TpgjzX5ZwGvA1uv6RMoSoZhq37sYCs72ved5nYnh38i0ZQRqUOvbqDJhLqBKkqI6kBbWLSvHZCVaDUQdE1FDfD4C4cp9zezdn4h6xbclLC+ZSr9cQNVFCXBRHr8lPpymPj5G7jcEWRFaX5Yucd4uXzGilsVBCFh5a4xHK0ovZIYVAAoSgoQLb//8ZaLLCnOi1u070AQGSdgG61VCCQHKgAUJQXoLr//Ew/cltSTarTAtIXTxvDykZaw89QzKDGoAFCUJCaax0+5v4Wp3eT3TzYi1UEA997qZc+x8wmNX1BCaDZQRUliuvP4sfP7u1fWqeJZE1mkXnMGJQ4VAIqSxMQzv38iKfXlcPPY4Wza18Da+YWaPjpBqApIUZKMVPL4uVaqA23UNbc7xWQ0Z1BiUAGgKElGqnr8xIq7mIy9m9GcQYlBVUCKkmS4deRzJ+ew29/C+kVTWFnmG5T8/vEm0jNoRWk+m/Y1MGPiqJT9TKmK7gAUJQlxe/wsLvamhMdPrETLGbR2fiEnzl1KSlfWdEYFgKIkIe6Jsaq+rYtNIBVVP5FokFjiUQGgKElGpkyMGiSWeFQAKEqCifT6qWtqZ/W8AkfNkw5qn2hokFjiUQGgKAkm0uunaPxINlc2hk166aL26Y1kK3KT7qgAUJQEo5NeOO4gMS0sH19UAChKAogW7DV3cm6XSS8T0SCxwUMFgKIkgGjBXrv9zV2CvTINDRIbXDQQTFEGEXe1LFvtM3XcCN5saONHaRTsda1okNjgojsARRlE3Ct/W+3zZkMbdxTmpFWw17WiQWKDi+4AFGUQiZbmYUlxHlX1rSmb3jkeRO6C5vhGZ+yuKJ7oDkBR4kw0g+/UcSOcNA/JXtUrEWiQ2OAQkwAQkbtE5KSINIjID3o4734RMSJSYr1+SEQOu36CInKbdWymiLxjXXOTiMiAfCJFSTKiGXxttY+d5iGT1T7R0CCxwUGMMT2fIJIF1ANfA5qAQ8A3jTHHI84bDlQAQ4E1xpiaiOO3ALuNMT7r9dvAWuAg8GtgkzHm1Z76UlJSYmpqano6RVGSBrfB156s1ODbP+z7pZXE+oaI1BpjSiLbY9kBzAYajDGNxphPgeeBb0Q57yfAz4DL3Vznm9Z7EZFxwAhjzAETkkDPAotj6IuipAxq8B147Cypm/Y1MHdyuJ1E1UF9JxYBkAeccb1ustocRGQGMMEYU9HDdR4A/sV1zaaerum69qMiUiMiNa2trTF0V1ESR2QRd7uc46JN+x0//+NnL6Zlds/BwPYMWlLsZbe/ha37A067qoP6Tr+9gETEA2wElvdwzu3AR8aYo329vjHmaeBpCKmArrGbijIouIu426vTyx2dHGu5yBLL4Ktqn2sj8r5N9Y5gQ8UJjrdcoqq+Ve/nNRDLDqAZmOB6Pd5qsxkOTAcqReQ0MAd4yTYEWzzI1dW/fc3xPVxTUVIKe+XvdvN8/IXDLH/mECLCkmKvGnz7SaRn0MoyH1O9Iyj3N2vOoGsklh3AIWCSiNxIaJJ+EFhqHzTGtAOO2BWRSuD7thHY2iH8NVDmes9ZEbkoInMIGYG/Dfx//f40ipIgIlf+cyfnUu5vZugQDztWzAozBNvn6Gq1b0SqyaoDbbz3/kdOzqA5vtEAzj1WeqdXAWCMuSIia4A9QBbwjDHmmIj8GKgxxrzUyyW+DJwxxjRGtH8H2AFcD7xq/ShKyuD28nHr+yd+/gaOt1xkmncE773/kXO+e+Wvk3//cOcMAli1s5aHdxwiO8vDlmUz9f7GSExxAMaYXxtjJhtjfMaYf7Da/lO0yd8YM8/tAmqMqTTGzIlyXo0xZrp1zTWmN39URUkyIv374aq+f3Gxl4q1ZWxZNjPsHDX4DgxudVCpL4cVpflc7ggy8fM3qGdQH9BIYEXpI6rvTzzRcgYtKfZyvOWiegb1Ac0FpCh9RPX9yYN6BvUPFQCKEgOq709OonkGHW+5RLm/mbXzC/Xe94KqgBSlB2x1j1vfXx1o4+UjLarvTwIicwZVB9qoqm9l7fzCjC6sEyu6A1CUHnCre+xVf0dnEAFL3z8uqr5fV56Dj6aQ7ju9JoNLJjQZnDIYuNU9EJpYVu2s5Za8kfzuvQ+43BFkWLaHZ5ZH1/criSHyewOrvnBTe8bvxPqTDE5R0h53Dh971b91f8BxIezoDFIduADAl3yjyc66+uiop09yEC2FdF1TexcvIHUNvYoKACWjiabjB7htwkg2VJzg5LlLrNpZiwDDsj1kZ3n47vxC1fenCJHfq7qGhqMqICXjiJanf/W8AhpbP+SVurN0dAbJzvJw581jKPc3Myzbw5LiPO691QuEpxpQ9ULyozUEVAWkKL2u9i93BOnoDHK5I8idN3+BqvpWR91z763eMBdQ29Crk3/y464h4E4ap6gAUNKcaLr9Yy3tLJw2xskfc+j0BywuzqPcH0pIa+eaXz2vgP+5co6qe1Kc6kAbW/f/niXF3jDXULUFqABQ0gj3ZG//neWBR3bU9Lraf/3d846Of1h2FusXTWFzZaOmc0hxbPXPugWTqKpvY/W8AsfAr7YAtQEoKU5v+nyAtV8tZNMbDVF1+3dPH8tufwtfmZLLvysrAFTHn05EGx9zJ+fy2tFzbFtekjHqILUBKCmPe4Vv417hl/pyWD2vwFnh21z6+Eqvq/3DZ0Kre9Xxpxdu11DbFlDub2Zl2Y0ZM/n3hEYCK0mJe+Vm/21P9tuWhxYyLx9pYc+x86xbMCnMy8PW56+dXwjApn0NliePt9vVvnvS1+Rt6UmkLWCOb7SzM8jUnZ4KACXh9DbZZ3lgxfZDDB3iYd2CSU46Bnfxj0sfX2HTvgYrFXMoF8z26tNc6QxG1e1D+Go/WhCRkj64bQGbKxsdW8DqeQVsrmzM2ApiKgCUQSVauL57si8aP5JVO2sBwiZ7j4TOdatzHi0rcFZwdj743f4W1i+awjTvSLZXn6bTwN8tnMw070hd7Wcw7qyh9liYOzmXjXtPZZQtIBIVAErcsCd7Oxy/1JfjTPbrFkyiMxhyzdxc2RimxrFxT/aR6hw72+Pw64c4K7i6pnbWLxrB5spGFk4b45QLtCd7Xe1nLm71jjsuINNTRqsAUAaEnib7+2Z4+efXTznb7/tmeNlQcYLFxXk8/dtGZ2Vmq3GiTfaR6pw5vtHM8Y12hIl7JT/NOzIsI6f7dyY/7EoIe8f4Jd9op5i8O/FfJtkD1AtIuWaiBVmdef9DHtlRw9b9AWey33XwDDO/OIoNFSeYOzmXV4+edwy1dmSm/VDak/3W/Y3OZD/8+tA6pdPA9xZMdgKzALYtL6EzGN4v9d5RusOdufW71kJj1c5ap85DpsUGaByAEhPRVvhb9wfYuPeUo87J8sCGihN8qTCHtxraWFycR1V9q1MycXb+KN4+/YFTM9f22ok0xK3aWcsnV4KO7t5e5dsr+8fm+jJupaYMDD2l+j5x7lLa5gnqLg4gJgEgIncB/wxkAb8wxvxjN+fdD/wKmGWMqbHaioAtwAggaB27LCKVwDjgY+vtC4wxf+ypHyoA4k80jxy46nJ59/QxvPi7Fkedc/f0Mew6eKbXyX7u5Bx2+1sc4bB+0RRWloUmcnuCX1nmC/ufOtkrg8FDWw/wVuACa+cXsm7BTUD6qYK6EwC92gBEJAv4OfA1oAk4JCIvGWOOR5w3HPhb4KCrbQjwHLDMGHNEREYDHa63PWQLCiWx2BOvuwKW2/1yy7KZFOR+xlnh2zp8tzrHdsG0vXHuKAxN+ktvn8CrR8+zftEUNu49xdLbJ7C5spFp3pCg2ba8xEmzEGmss3+n46pMSTzVgTbqmtsZlu1x7AEQHg2ezsRiA5gNNBhjGo0xnwLPA9+Ict5PgJ8Bl11tC4A6Y8wRAGPMBWNMZz/7rFwD0fLkuJNh2QZbwCl9+E976x33ywOBC2yubGRxcR5vNrQxK38U5f5m5k7OCZv0754+hqr60Aq/9g8fsPT2Cbz4u1BitZVlPrYtL2HC5z8TlltHdfZKIrB1/luWzeSZ5bMAeHjHIVbtrE1bVVAksXgB5QFnXK+bgNvdJ4jIDGCCMaZCRP7OdWgyYERkD5ALPG+M+W+u49tFpBP4V+C/mij6KBF5FHgUYOLEiZGHlSj05n75hwsf8vPfNACwZdlMqgNtXVwxo7lfdrfCX79oCp1BWL9ohGMTWFnmc3T27hW+ezWfCQ+Ykry4YwMAVpTms2lfAzMmjsqYsdlvN1AR8QAbgeXdXP8OYBbwEfCGpYt6g5D6p9lSHf0rsAx4NvICxpingachZAPob3/Tie5qoP7hwoc8/duu0Y5u90ubA4ELYUUybFdMt/slXE2R3J06xx1ko5O9kgq4d51uLzQ7ZXQmjNlYBEAzMMH1erzVZjMcmA5UigjAWOAlEfk6od3Cb40xbQAi8mtgBvCGMaYZwBhzSUR2EVI1dREASoi+5MZ5cmkx997qtaIdo+vr3St7OximOtDG9urTXdwvASeNQrQVvkbWKqmM2zW01JfDHN/osNfpTCwC4BAwSURuJDTxPwgstQ8aY9oB5y5Z3j3fN8bUiEgA+PcicgPwKTAXeMIyDn/OGNMmItnAPcDrA/SZ0gb3pG8bZ1fPKwhT4XSXGwdwoh1nW/r6yDw5QJeI2nuKxjmlDyPdL92TPugKX0kPIlVBkRlh05leBYAx5oqIrAH2EHIDfcYYc0xEfgzUGGNe6uG9H4jIRkJCxAC/tuwEnwH2WJN/FqHJf+sAfJ6UJZYVvl3MxK3CiZYbB+iSH8etr7fz5ABdImpXll3dFtu6+8iJPt0fCiWziOaAkCnjXAPBEkC0yf5YS7uTmOpYSzv/fU89Q4d4ui1mEpku4dGyAkeXD4Tp/lfPK2Dj3lPcN8PLq0fPs3DaGGeVr772itKV7uxrqfqMXHMcgDLwuH3t+5L98u7pY7tNdWyv5Nfs8rNw2hhnCxtpnI3c2urKXlG64n5G3dXE0i02QAVAnIm2kgBYOG1Mn7JfXmuqYxvV1ytK7Nh2AHehoXQ0CqsAiBPRImsh3FMn97PXxZz90l3MRFMdK0r8yYS00SoABpDuvHYWThvTxVMHCMt+6Z7s3dkve1rhg6pwFCVeRMYGuNNGpwuaDnoAsSf9aAXKbdXOitJ84GquETv3iDvV8ca9p1j71UJ2rJhFZ1ALlSvKYOPW+a9bcJOjDrLTqaQL6gU0ALhX/vbAmTs5l9eOnuOu6WMp9zeHeerYXjiRGTfVI0dRkoNM8QJSATAAREYSPv7CYcr9zdxRmMORpj91Uf1kSpShoqQLqS4QuhMAqgIaANweA4+/4Ge3Nfm/ZWXNfGb5rLAqVu5MmIqiJD9u9S6QNtXD1Ag8QJT6cpg7OYdyfwtLir3cNHYEc2/KYXNlo3NcPXUUJTVJV7dQFQB9pLut4MtHWnjt6HmnAtZflUwIC8DSRGmKktq43UKXFHtTVh3kRlVAfSTaVnDVzlpeqTvLtuUlPPFAcZjHgHrtKEp6EJlfa+v+gNOequog3QHEiHvlb0/wtqfP4mKv49UDmZVNUFEygUhHj6neEWyoOMHxlktU1bemrDpIBUCMROYGsYufLynO46f3FXU5X9U9ipI+RKaMXlnm43jLJScxY6o+66oCipFonj5LivOoqm9Nu+AQRVHCiXTcqA608drRcywp9joVxOx2u852KqACoBfcxdTdnj5TvSN44oHb0jZCUFGU6NjqoHULJlFV3+aUXt26P5BytgBVAfVCZDK3infOkZ0lvPf+R46RV/X9ipI5RKZZt+2Bdj2PVJoHNBI4BmxPH43oVRQlkoe2HuCtwAXWzi9k3YKbgORzC9VI4H5Q6suhKG+kk8zNNvBqRK+iZDbVgTbqmtsZlu1he/VpqgNtKeUWqiqgKEQGe9lfcqlvdFhaWPX0UZTMxZ7obY3Aqp21PLzjkKMlSIW5QXcAUXAHe9nqH4A18wvV6KsoChBuCyj15bCiNJ/LHUFuyetaATBZ0R1AFNwunzePHQ4QJtHV6Ksoilu/b0cJf8k3mrrmdsdBxD6WTPYANzHtAETkLhE5KSINIvKDHs67X0SMiJS42opE5N9E5JiIvCMiw6z2mdbrBhHZJCLS/48zcNh5P94KXHD0/u5jyfhlKooy+LijhL9rlXddtbM2JewBvQoAEckCfg7cDUwFvikiU6OcNxz4W+Cgq20I8BzwmDFmGjAP6LAObwZWApOsn7v680EGmshycKryURQlGpGqINsm8OS+hqT3FIxlBzAbaDDGNBpjPgWeB74R5byfAD8DLrvaFgB1xpgjAMaYC8aYThEZB4wwxhwwIT/UZ4HF/fgcA0qmlINTFKX/REYJ216D1YELfOv2iWGqoGSLEo5FAOQBZ1yvm6w2BxGZAUwwxlREvHcyYERkj4j8TkT+veuaTT1d03XtR0WkRkRqWltbY+hu/4nM+6Eun4qixEoquYb22wgsIh5gI7C8m+vfAcwCPgLeEJFaIOaZ1BjzNPA0hALB+tvfWIim31eXT+VacbsV23+/fKQFgJ/eV8QPX6wLO/+n9xU5hsOi8SOT1oCodCXVXENjEQDNwATX6/FWm81wYDpQadlxxwIvicjXCa3sf2uMaQMQkV8DMwjZBcb3cE1FSUmiFQzK8sAjO2rYtryEovEjWbWzliudQYZkeSjI/Qyv1J2lM2gwxjhtG/ee4r4ZXp7+baOThiSZvUmUEJHagxWl+Wza18CMiaOSbvKH2FRAh4BJInKjiAwFHgResg8aY9qNMTnGmHxjTD5wAPi6MaYG2APcIiI3WAbhucBxY8xZ4KKIzLG8f74N/O+B/Wix4074ZpOM+joleehuzPzhwoddCgZtrmxk3YJJrNnl50DgAgBDsjzcefMX2FBxgjtvHkOWR8LaZn5xFLsOnmH1vALqmtq7JBrT8ZmcuO0BbtfQdyzXUJtk+f56FQDGmCvAGkKT+bvAL40xx0Tkx9Yqv6f3fkBIPXQIOAz8zmUn+A7wC6ABCACvXuuH6C/pWvBZGXjsiT8yWPCHL9axZpefe2/1Ok4DG/eedJwJVpb5nHKCK0rzWVGaT7m/hVn5oyj3N3dpe7OhjcXFXjZXNnLy3EU2VJzgtglXJ397fCbLRKKEkyquoZoMzsL+UtKp4LMyMLjVOvY4WT2vgMbWD3ml7mxYkkB7zGzce5JN+xqcBGHu8bW9+jQAd978BXb7W1hcnMfr757v0lZV3+oqPOTl9Xf/qAkJU4Ro6WRW7azllryRnDh3adC/M00G1wvugs9u1y1Fca/2S305rJ5XwIaKE1zuCNLRGQxLEghdY0hs9c2TS4uZ4xsNwJXOIK+/+0fWL5rC6++epzNowtqq6lu5e/oYV+GhNu68eYzzPw8ELjjXrGtqVxVmkhHNNXRFaX4X19BEo6kgLCIfWjvhm5K59FwHOo9yfzPDsj1hYwbCV+VzfKN5ZEcN6xZMcryAtiyb6XgBrSzz0dj6Ydj/XVkWMvJu3HuK9Yum0BmEqd7hbKg4wZLiPF49etbZXdhj1P0/3eoHJTmoDrSxdf/vnQpi9vySaMN+RquA7AccCHtgXj7Swp5j53VrnYF0p+7pDMLJc6EasHcU5nCk6U9R1TELp43h3lu9XcoH9vUh76vaqTrQxiM7arhr+hiq6tvChIF6DiUW9/e3ubKxy+/BmGe6UwFltACwvxj7oYVwQaAPTubQ3WLgF/sb+c2JVr5UmMNbDW3O769MyeXflRV0OT8eYybWhcrjL/gp97ewpNjLTWNHkOUhbIJRYZAYoglzeyc5WBXEVAB0gxp/FaCL2sRdAe7W8Z/jzYa2hE+s0WIM3AFjoYklh93+FkdQrV80hZVlvrDPp+M7sUQ6CAwG3QmAjLcBuI2/bp2qkv64J1Rbz297atjG3bunj+W1o+dZUuylqr6NvyqZ4NSCtVOCD1aUeHcR6hDpDSSOqmpzZSOXPr6ii5skIdlsjRnvBaRZPzOXyPgPgI7OINVWsNaSYi+7/S2sWzCJJx4oDksKmEwpwd3Rp9WBNqrqW1lSnEftHz5g7uRc9WxLEpIxyWRG7wAit8VzfKN1m5wBdOfdU1F3liwPDMv2kJ3lYVh2FusXTWFzZSPTvFfPT7ZiQLYgihzPU70Bx3PouYPv0frnTwbEQK1cGz0lmUzUeMpoG0BPOlV9INKXyIny8RcOU+5vZugQD/fPyEtZh4CePJjsHERAmOeQLngyAzUCu9CJX7nqjREymk71juC99z8Ki+ZN5THR3Ri3PYduHjucuub2tPm8qcpgzUUaCexCc/8opb4c5k7OodzfwuJiLxVry9iybGbYuEgmPX9fiYxEhdDn+el9RU6p047OoHNMn4HEkOi5KCN3AKDun5lCTyvh3f6WjAucipaTaEVpvj4DCWQw5iLdAUSguX8yg2grrFU7a3ml7izblpcktXfPQBPphbJl2Uw+/rSzyzOgeYQGl0TORRkrANT9M31x5+p3+/cv3XqANbv83FM0Lkz3nSklPyO9UACys4QhHkn60oXpTCLnooxUAUV6P6g3RHoR7ft9eMchLncEBzX6MpmJFvn88aedZGcJ25bPUsPwIDFY6WhUBeRCi76nJ/bK3+3f//gLh1n+TKgmq+72ruJ+BuxUxVeCho7OqwtC3Q3EH/t7uPdWL2t2+QF4cmkxLx9pGZR7n3E7AHUBTV968u/fsWKW7va6QQ3DyUE8jcG6A7BItNuVMrB0p+9ftGk/u/3NTPOO4LohV4e57vbCUcNw8pAIY3DGCQC3esBds1VXOalJtHw+lzs6OdZyMS39+wcaNQwnD4kwBmecCsgmESlZlfgQqcL45EqQRbeMzSj//oFADcOJI96OKaoCcqEuoKlPpOrH3jp//GknO1bMyij//oFCDcOJw773dn1nt6oynuq3mASAiNwlIidFpEFEftDDefeLiBGREut1voh8LCKHrZ+nXOdWWte0j32h/x+nd5IxJavSd9yqn+pAG9urTzPEI2RniXOO6vv7hjt9hHuRdP3QLFbtrFWVaRyx7717XLtfx0vg9qoCEpEsoB74GtAEHAK+aYw5HnHecKACGAqsMcbUiEg+8IoxZnqU61YC3zfGxKzTUS+gzCbyuwvVwT1ER6fh+qFZYbV5dZK6dqKpI7697W2uBE2YylSfm/gQD2+g/qiAZgMNxphGY8ynwPPAN6Kc9xPgZ8DlfvU0jujkn9pEL+BiuBI0rCjND6vspav+a0cNw4llML2BYhEAecAZ1+smq81BRGYAE4wxFVHef6OI+EWkSkTKIo5tt9Q/fy8iEuW9iMijIlIjIjWtra0xdLd71AU0tYn04Fq1s5brh2Z1seWovr9/RKqC1uzys235LJ59ZDYAD+84xKqdtbrLihODaaPstxFYRDzARuB7UQ6fBSYaY4qBdcAuERlhHXvIGHMLUGb9LIt2fWPM08aYEmNMSW5ubr/6qi6gqUlPBt8ty2aqLSeORDMMX+4IMvHzN3TZSWucQP8ZbBtlLAKgGZjgej3earMZDkwHKkXkNDAHeElESowxnxhjLgAYY2qBADDZet1s/b4E7CKkaoo7mgU09VCDb+KIZhheUuzleMtFtu4POO26kx4YBtsbKJaawIeASSJyI6GJ/0FgqX3QGNMOOLOo27grIrnA+8aYThEpACYBjSIyBPicMaZNRLKBe4DXB+pD9UTk9mqOb7QKgSTHHeHb0RkkO8vjqCPcuzj7Rxl4utYbHsGGihMcb7lEVX2r7qQHCLfqMlJD4Y7RGCh63QEYY64Aa4A9wLvAL40xx0TkxyLy9V7e/mWgTkQOA78CHjPGvA9cB+wRkTrgMCHBsvWaP0WMqAtoahGp+inKG8nljiC35I1Ug+8gE2kYXlnmY6p3BOX+Zk0ZEQcGS12dUZHA6gWUWkSLTLV3AO58/srgYxfWcX8foC64A81AZSzI6KLwOvGnLjrRJB8qmAeHgYwHyOhUEOr+mbq4VT/q658cqGdQ/AkFOdawel5BmLp66/7AgN7TjBAA6v6ZulQH2nj33CX19U8i1DMo/tQ1tbNuwSQ2VzY63kCr5xWwce+pAb2nsXgBpQVu98+18wt18k8BIj1P5vhGq/BOIqJ5Bv1DxQmqTrZx/OxFzcTaD+x7Nc07MkwNtG15yYCO/YzYAYBmAE123B4/Ni8faWHhtDFaujNJieYZdEdhDm82tDF3ck5YWmPdCVwb8Y5byogdgK4kkx/bTuNeNe45dr6L37P6+icPkSv66kBo5b+k2MtufwsgGiPQT+Idt5QRAqCnIvA6MJMDt50mHjVRlfjStYCJUO5vZklxnn6H18gPX6zjlbqzjmfVHN9oVu2s5Z6icfz0vqIB+R9prwJSF9Dkprs8P1PGDteJI4VwL7KqA21U1beypDiP146eU3VrEpP2AkBdQJObaHl+hmV7eKe5XSeOFML2DHLvBJ544Da2LS/RaPtr5Kf3FTn1rG3vxS3LZg7Y6h8yJBAsHgUWlIFDg73Sh2g77h++WAcQNnHpLjx2BiIaOKMDwTQDaHKjwV7pgztGwObeW73sOXZed+HXQLy9FzPCCKwZQJOLaKUd65rbKfWNDvt+1OMnPVAD/7WhRuABQDOAJh+Rev9VO2sBWDO/UL+fNMW9C7djBGw0ZUTiSPsdgLqAJh/uFeHNY4cDhCUR0+8n/XCnjNjtb2GqdwQry3xdEsspV/npfUXce6s3bOc00Mn20l4ARDMyqWoh8fSUmkO/n/RCi8lcO/FOYZPWKqBo6QV0u5k43N/H1RVhHlv3/15VPmmMFpO5duJtBE5rAaAxAMmF/X1s3R9gzS4/q+cVUFXfyroFk1Tvn8ZEegZVB9p47/2PGJbtYXv1accWpM9mOINhv0z7OACNAUgu7Dznd00fQ1V9m2aMzDC0mEzsDGQWg4yuCDZQZdWUgUG/j8wlclKzx0KpbzS7Vs5JcO/Sl4wNBPvhi3Vsrz4dpkNTXePgorp/xSZaMZm18ws5ce6SjoUEkNYCoDrQxit1ZwGY4xvNk0uLWbWzllU7a1XXOIio7l+JJJp++5EdNU5FMfd5uliLHzEJABG5S0ROikiDiPygh/PuFxEjIiXW63wR+VhEDls/T7nOnSki71jX3CQi0v+PE05dUzv3FI1j7VcLWbPLz4HABQBm5Y/SFAODiO33v3HvKeZOzmFzZSNPLi1mZZlP0z1kKNHic9YtmMTGvacy3mljML0XexUAIpIF/By4G5gKfFNEpkY5bzjwt8DBiEMBY8xt1s9jrvbNwEpgkvVz17V9hO55bK6Pe2/1srmykbmTc9i0r4E7b/4Ch8+0Z9ygSjSlvhxWlt1Iub8lzPVPa/tmJtFyBq0s8znZQx/aeoBVO2vDhESm7AYG03sxlh3AbKDBGNNojPkUeB74RpTzfgL8DLjc2wVFZBwwwhhzwISs0M8Ci2PudR+wiynv9rcwO38Uu/0trJ5XoN4GcSZyFWOnerbz/ajaR4mGHfj0VuACHZ1Bpz2TdgPuSHk7DXS8vBdjEQB5wBnX6yarzUFEZgATjDEVUd5/o4j4RaRKRMpc12zq6ZoDRXWgjY17T/GlwhzePv0Bi4vz2FzZyNb9gYxYTSQKzfejXAtuw3B2lodVO2vjPgkmI4OVwbjfRmAR8QAbge9FOXwWmGiMKQbWAbtEZEQfr/+oiNSISE1ra2uf+1fX1M59M7y81dDGkmIvVfWt3D19DBv3nsqI1USicK9ifr6vAbia70dTPSvRiDQMb1k2k48/7ewyCaazKsjeObsF4fbq005NhYEmFgHQDExwvR5vtdkMB6YDlSJyGpgDvCQiJcaYT4wxFwCMMbVAAJhsvX98D9d0MMY8bYwpMcaU5ObmxvapXBSNH8mrR8+zftEUqurbmDs5l10Hz7BuwaSMWU0MNvYgdm/n77x5TNiEr7p/JZJIwzBAdpYwxCMZEzFcNH6k46n45NJi5vhGA/BK3dm47JhjEQCHgEkicqOIDAUeBF6yDxpj2o0xOcaYfGNMPnAA+LoxpkZEci0jMiJSQMjY22iMOQtcFJE5lvfPt4H/PbAfLYQ9qFaW+bh57HDK/c0sLs7DVi+m82oiUbjdPm2f/93+ZrLS2ulY6S+RMQJrdvnZtnwWzz4yG4Bvb3ubR3YcSlvDsP057ikaB8CBwAUn//+WZTPjsmPu9ZE0xlwB1gB7gHeBXxpjjonIj0Xk6728/ctAnYgcBn4FPGaMed869h3gF0ADoZ3Bq9f2EXrGXau0rrmdIR7htaNnKRo/0hlkWR7SZhAlA7bhfUPFCeZOzqGqvpX1i6awubJR9f5KTLh3A6W+HFaU5nMlaOjovJq5IN12A/bC6d5bvawozWfTvgY6OoPce6s3bjvmjEgF4dYtHmtpZ0PFCUTAI8IDs8bz6tHzTm6Sl4+08MXRn1H1RD95qirAyXMXKfe3OCkfNN+Pci2483ltrz4NQFHeSOqa28PyB6XD+HLXxwYGLEdSxqaCgPDVxMoyH4uLvQQNdAYNuw6eYfW8Al4+0sIjOw7xSt1ZZ0WRTtvLwaZo/Eiq6tvCUnCo3l/pK9EMwx2dwbR2E+3oDHK5I8ijZQVsWTYzrh5zGSEAInWLVfVtzM4fhQGyPMI/7a3nV7VNXO4IsvarhY7K6JEdNV301ioUohOZ78dO+XDDdUPU7VO5ZqIbhj2U+kaTneVh+fZDPP6CP8xNNJWf0ZePtJCd5XEWTkBcPeYyQgDYuCemhtYPWVKcx5Wg4XJHkI5Ow+LiUNSw7Xe8bsEkNlc28sMX67p4IKTyIIsHbr//uqZ2Vs8rYHNlo5P5Ud0+lWshmmF4y7KZ7Fo5hy3LZmKModzf4tQZTpWdQLR0D1v3B9jtb2HLsplh+f8hemXDgSCjBIB7YnpyaTF/VTKe64aEbsHQLOH1d//I3Mm5jt+xnavmlbqzPLzjEKt21rJw2hiOtbSHDbJMFwb2Z7cH7EefXGHTGw0snDZGUz4oA0a03cCw7CymeUew29/Cok37UyZ9RLR0Dxv3ngpzTx+MhVNGCYDH5vroDBJWjGLoEA8/WjSF+2eO50pnkN3+ZpYU54XprVeU5lu7hCCXOzrZUHGC1fMKqGtqdzJcZrIwsAcz4EQv2t4LijJQdLcbqFhbxuLiPI61XOSTK8ltF3DHyNgLpsdfOMwjO2rYtryElWXhi6R4L5wySgDA1UFkZwrdsmwmK8tCSeOGZHn4ypRcbho73PlybF/2tfMLASj3tziqopPnLjrCIFPtBsu3v82xlnYn1fbT+xsZ4pEwdz1FGWjcu4GQXa+VJcV5YEhqu4B75V/qy2Hu5FzK/c3cNX1sQgJTM8INNBailV/buj/Axr2n2LY85D3lLl93581jKPc3W+kl2pySk7aKaeG0Mc4K2F0CL9Xd1CJ5eMfb/OZEK0tvn8C//q6Zyx2hFVjxhJH84f2PMyp/izL4uL2E7In+b555m45Ow5JiLzeNHUGWB0ftmwzlR+0+z52cw25/C4uL86iqb43rs9KdG+iQuPy3FCTaYOgM4kz+9nYT4Bf7Gx1VUVV9q2M3WDu/kJVlPqZ5Q+Hc5f5msrM83FM0jmMt7c4ghPTwWc7/QQXXZQnDsj38z4Nn8LgqOvxF0TimeUdS19SuAkCJG93ZBSaPuYHd/ha+VPgpbzW0sX7RFOqa2pPiOQyt/HMo97ewpNjLEw/c1kWQDRYZpwLqC251kfuLOXymnfWLpnDT2OFWqunY7Aa3TbhqJ0gXb6JPOg1XLH/soGszubmyEYif94KiQO92gTcb2vhSYU6YynawnsPuCrv88MU6Xjt63tEeuG0Cg+0ppyqgPuJWFbndSjuDV/V7throW7dP5On9jVzuCLKk2Mvr7/7RUSHdUzSOgtzPJNXWtC/M/++VnHn/QzqCXY9dlyVsf3h2ynwWJT2I9mzOnZzLa0fPcdf0sY7K1v0c2rv6gVp99zY/2GnR7ejewVr5qwpogHBPaNG2n6vnFYTZDezQ9dff/aNjNwCcXcH6RVO6DIRUYOT1Q2gMhraQkTLg007DsRad/JXBxR5vkZPqVG+ADRUnHJWt+zk8ELjAcwffC1t91zW1h03i9uvIBY17srf/zvLgePQA3DZhJBsqTrC4OI+nf9vIPUXjnNw+EO7qmQhVqQqAfnCtdoNXj5519H+bKxu59PEVnjv4HgunjelyvWTcFTxVFeAvisZxrOUin0Z4+2R7YEiWh1fqznZxaVOUwSDSQ2hzZSPrF02hMwhTvcMdYfDq0bOO7c6efO0Vu/17495T3DfDy9O/vWo3sHPz33ur1xE0WR5Ysf0QQ4d4WLdgUpjDyOLiPMr9zU5OrEjshHeJQG0AA0xvdoNh2R6yszwMy/Z0CTyzB5Stj0zWGIOi8SPZXNlINPVhRxCCQcPd08cloGeKEm4XcKeDt8dt5HNo1xqwV+N2DfENFSeY+cVRTr4wW6C8UneWV+rOAjjuz/+0t95xgrj08RUnn8+dN3+BqvrWsJxYyYTaAAYBe3sI4S6hv9jfyG9OtIa5gdnn2C5i6xdNYWWZL2FeAt1RHWhj6daDYW3ZHhybwOl/XJSAXilK93T3HL58pIU9x847z9bGvSfZtK+B2fmjePv0B11cvd3PqdvOZ8cKbdrXwLBsD3dPH5s0z7DaABKIrb55qioQtjW1dwWdQfirkvHO4LCjaZcUe9m49xTHWy5SVd+WFMZi+yGqqGtx2m4aO5xT5y/REQwXAoqSTER7DiGkgrn31jbHBhAqYuRlt78lqqu3/T77OR2W7XFKN17pDLp2F1lOHYxp3pEJ1/dHQ3cACSJa4Fl1oM1ZjdirjanjRvCmVc84GYJa7FVMR2eQS5evcEdhDm81tLH09gn8r5omRn/2Ov7th18dlL4oykDi9trZXNno/L57+hh2HTzTZafu1vOv/Wohm95o4JMrQf5u4WSmeUcmVQCo7gCSjO4Gg3srOvz6IWyoOMEdhTlhQS1fmRKqjezeUg6GILCF1up5BfxDxQnuKBzNkaY/8ZUpubx69Dx/d9dNdOrqX0lRbHtBpP1u495TYTt125XT9uiBkOfPugWTwoIf7Wu5bRLJhu4AkoiefIhPnrtEub+ZOwpzONL0p4TEE9h9WjhtDJc7Oin3tzAs28Mzy2cBiV/lKMpAE22nbnsB/fS+IqctGb313HS3A1ABkKTEEtQyWIamyL6s2lnLJ1eCBIOG64dmDUjJOkVR4oeqgFKMWIJauosnGGgvAzvC2dZnfnIlyKdXgiwpzgszXqsQUJTUQuMAkpzuglp6iieoa2qPmoOkrzEE0XKXr3/xHWfyr6pvBeJbsk5RlPihAiDJiRbUMs07kj3HzrNl2UyeWT6LWfmjwhLSZXkYkICyyNzlU8eN4PSFj7ijMIcnHrhtUErWKYoSP2ISACJyl4icFJEGEflBD+fdLyJGREoi2ieKyJ9F5PuuttMi8o6IHBaRzFDs95NYspPakYx2OHtfMyC6MxjaK/9VO2tZtGk/bza0cUdhDsfPXkxoBkNFUQaGXm0AIpIF/Bz4GtAEHBKRl4wxxyPOGw78LXCw61XYCLwapf0rxpjkio1OAXpLSGdPyu6Astff/SPVgUNRMyC6cev77Wte7ujkWMtFK3d5cRe7hOr+FSU1iWUHMBtoMMY0GmM+BZ4HvhHlvJ8APwMuuxtFZDHwe+BY/7qqRCOaj3GpL4ei8SOdUpZV9W3cefMYpz7Bz/c1OAXubdy7gYXTxrBml5+Ne0+yamctIpIUucsVRRlYYhEAecAZ1+smq81BRGYAE4wxFRHtnwX+A/BfolzXAHtFpFZEHu3un4vIoyJSIyI1ra2tMXRXca/Q1y24KaxoDcBbgQt0dAYpyP2MU/d4zS6/Yzu491ZvWHH3HStm8cQDxY7O3xYCqvdXlNSm30ZgEfEQUvF8L8rh/ww8YYz5c5RjdxhjZgB3A98VkS9Hu74x5mljTIkxpiQ3N7e/3c0IYvEcEmDTGw1O1sO5k3PDSuU9d/A9vuQbTbarwr2u/BUlvYglDqAZmOB6Pd5qsxkOTAcqRQRgLPCSiHwduB34SxH5b8DngKCIXDbGPGmMaQYwxvxRRMoJqZp+28/PoxDdRgChHEK2/v/lIy2U+5sp97cwO3+Uk68cwqsjRdP3q85fUdKDWATAIWCSiNxIaOJ/EFhqHzTGtAPOjCAilcD3jTE1QJmr/T8DfzbGPCkinwE8xphL1t8LgB/3/+MokXSXARHglbqz+HI/y6HTHzgupK1//qRLpsRky2CoKMrA0KsKyBhzBVgD7AHeBX5pjDkmIj+2VvnXwhjgTRE5ArwNVBhjXrvGaykxEK149tqvFnK2/TLrF02hqr6V1fMK2HPsfJf3qr5fUdITzQWUgdi5fWKtfaooSmqjyeAURVEylO4EgKaCUBRFyVBUACiKomQoKgAURVEyFBUAiqIoGYoKAEVRlAwlpbyARKQV+EMvp+UAqZJhVPsaH7Sv8SOV+qt9vcoXjTFdcumklACIBRGpiebulIxoX+OD9jV+pFJ/ta+9oyogRVGUDEUFgKIoSoaSjgLg6UR3oA9oX+OD9jV+pFJ/ta+9kHY2AEVRFCU20nEHoCiKosSACgBFUZQMJakFgIjcJSInRaRBRH4Q5fh1IvKCdfygiORb7V+zag2/Y/2e73pPpXXNw9bPFxLc13wR+djVn6dc75lpfYYGEdkkVsm1BPb1IVc/D4tIUERus47F5b7G2N8vi8jvROSKiPxlxLG/EZFT1s/fuNoTdW+j9lVEbhORfxORYyJSJyIPuI7tEJHfu+7tbYnsq3Ws09Wfl1ztN1pjpsEaQ0MT2VcR+UrEmL0sIoutY4m6r+tE5Lj1Pb8hIl90HRvU8YoxJil/gCwgABQAQ4EjwNSIc74DPGX9/SDwgvV3MeC1/p4ONLveUwmUJFFf84Gj3Vz3bWAOIMCrwN2J7GvEObcAgXje1z70Nx8oAp4F/tLV/nmg0fo9yvp7VILvbXd9nQxMsv72AmeBz1mvd7jPTfR9tY79uZvr/hJ40Pr7KWB1ovsaMR7eB25I8H39iqsPq7k6FwzqeDXGJPUOYDbQYIxpNMZ8CjwPfCPinG8A/7/196+Ar4qIGGP8xpgWq/0YcL2IXJeMfe3ugiIyDhhhjDlgQiPgWWBxEvX1m9Z7402v/TXGnDbG1AHBiPcuBP6PMeZ9Y8wHwP8B7krkve2ur8aYemPMKevvFuCPQJfIzQGkP/c1KtYYmU9ozEBoDC1Oor7+JfCqMeajAehTd8TS19+4+nCAUJ11GPzxmtQCIA8443rdZLVFPceESle2A6Mjzrkf+J0x5hNX23Zry/f3A7SV6m9fbxQRv4hUiUiZ6/ymXq6ZiL7aPAD8S0TbQN/XWPvb1/cm8t72iojMJrR6DLia/8FSGTwxQIuZ/vZ1mIjUiMgBW6VCaIz8yRoz13LN7hiQ+0poNxs5ZhN9Xx8htKLv6b3xGq9JLQD6jYhMA34GrHI1P2SMuYVQwfoyYFki+ubiLDDRGFMMrAN2iciIBPepR0TkduAjY8xRV3Oy3deUxFrt7QRWGGPs1ewPgSnALELqgf+QoO65+aIJpS5YCvwPEUnqGqLWfb2FUG1zm4TeVxH5FlAC/L+D+X/dJLMAaAYmuF6Pt9qiniMiQ4CRwAXr9XigHPi2McZZSRljmq3fl4BdhLZsCeurMeYTY8wFq0+1hFZ9k63zx7veH+2ag9pX1/EuK6k43ddY+9vX9yby3naLJfgrgB8ZYw7Y7caYsybEJ8B2Bm/Mdovr+24kZP8pJjRGPmeNmT5fM159tfhroNwY02E3JPK+isidwI+Ar7u0E4M9XpPaCDyEkBHkRq4aU6ZFnPNdwo2Vv7T+/px1/n1Rrplj/Z1NSFf5WIL7mgtkWX8XWF/s5010w89fJLKv1muP1ceCeN/XWPvrOncHXY3AvydkUBtl/Z3Qe9tDX4cCbwD/T5Rzx1m/BfgfwD8muK+jgOusv3OAU1iGTuB/EW4E/k4i++pqPwB8JRnuKyFhGcAy+idqvBpjklcAWB/6L4B662b9yGr7MSGpCTDMGnAN1g0qsNr/I/AhcNj18wXgM0AtUEfIOPzPWJNvAvt6v9WXw8DvgHtd1ywBjlrXfBIrcjtRfbWOzQMORFwvbvc1xv7OIqQX/ZDQKvSY670PW5+jgZBaJdH3NmpfgW8BHRFj9jbr2D7gHau/zwGfTXBfS63+HLF+P+K6ZoE1ZhqsMXRdEoyBfEKLFk/ENRN1X18Hzru+55cSNV41FYSiKEqGksw2AEVRFCWOqABQFEXJUFQAKIqiZCgqABRFUTIUFQCKoigZigoARVGUDEUFgKIoSobyfwE6pL7jVc/whgAAAABJRU5ErkJggg==\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "plt.plot(np.array(boundaryLocations)[:,0], np.array(boundaryLocations)[:,1], 'x')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "distanceFilter = 0.0032"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "sortedLocations = [];\n",
+    "filteredSorted = [];\n",
+    "initialPoint = boundaryLocations[100]\n",
+    "boundaryLocations.sort(key = lambda point: np.linalg.norm(point-initialPoint))\n",
+    "filteredSorted.append(boundaryLocations[0])\n",
+    "\n",
+    "while len(boundaryLocations) > 1:\n",
+    "    delta = boundaryLocations[1]-boundaryLocations[0]\n",
+    "    sortedLocations.append(boundaryLocations[0])\n",
+    "    initialPoint = boundaryLocations[0]\n",
+    "    boundaryLocations = boundaryLocations[1:]\n",
+    "    boundaryLocations.sort(\n",
+    "        key = lambda point: np.sign(delta.dot(point-initialPoint))/np.linalg.norm(point-initialPoint), reverse=True)\n",
+    "    if np.linalg.norm(boundaryLocations[0]-filteredSorted[-1]) > distanceFilter:\n",
+    "        filteredSorted.append(boundaryLocations[0])\n",
+    "\n",
+    "#filteredSorted.append(boundaryLocations[0])\n",
+    "sortedLocations.append(boundaryLocations[0])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "st = len(filteredSorted);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "filterX = sgn.savgol_filter(np.array(3*filteredSorted)[:,0], window_length=15, polyorder=2)[st:2*st]\n",
+    "filterY = sgn.savgol_filter(np.array(3*filteredSorted)[:,1], window_length=15, polyorder=2)[st:2*st]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {
+    "scrolled": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(0.35, 0.55)"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 360x360 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "plt.figure(figsize=(5,5))\n",
+    "#plt.plot(np.array(filteredSorted)[:,0], np.array(filteredSorted)[:,1], 'r')\n",
+    "plt.plot(filterX,filterY,'b')\n",
+    "plt.xlim([0.0125,0.2125])\n",
+    "plt.ylim([0.35,0.55])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Move along x axis as a function of radial compression\n",
+    "startPoint = (0.5+0.445)*0.5\n",
+    "shearVal = -0.5"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "for i in range(len(filterX)):\n",
+    "    currentPoint = np.array([filterX[i], filterY[i]]);\n",
+    "    scale = shearVal*(np.linalg.norm(currentPoint)-startPoint);\n",
+    "    normal = scale*np.array([-filterY[i], filterX[i]])/np.linalg.norm(currentPoint);\n",
+    "    filterX[i] += normal[0];\n",
+    "    filterY[i] += normal[1];"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "scale = 1.0\n",
+    "theta = -4*0\n",
+    "\n",
+    "centerX = np.mean(filterX)\n",
+    "centerY = np.mean(filterY)\n",
+    "\n",
+    "filterX = centerX + scale*(filterX-centerX)*np.cos(theta*np.pi/180.0) + scale*(filterY-centerY)*np.sin(theta*np.pi/180.0)\n",
+    "filterY = centerY - scale*(filterX-centerX)*np.sin(theta*np.pi/180.0) + scale*(filterY-centerY)*np.cos(theta*np.pi/180.0)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"360\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Max radius: 0.5007285610021447 at (0.17676177423050082,0.4684915868766098)\n",
+      "Min radius: 0.44909155658275357 at (0.036978412466203786,0.44756655729109146)\n",
+      "Min x: 0.022997204287084974 at (0.022997204287084974,0.45356369579002237)\n",
+      "Max x: 0.21096808365683925 at (0.21096808365683925,0.44975275029332273)\n",
+      "Min y: 0.44429312197716647 at (0.19643992016352538,0.44429312197716647)\n",
+      "Max y: 0.47231123826247445 at (0.15705086472735147,0.47231123826247445)\n",
+      "Max Delta x: 0.18797087936975426\n",
+      "Max Delta y: 0.02801811628530798\n",
+      "Points in old: 81\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5e9d6fe20>]"
+      ]
+     },
+     "execution_count": 20,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "circx = 0.55 * np.sin(np.linspace(0,2. * np.pi, 100))\n",
+    "circy = 0.55 * np.cos(np.linspace(0,2. * np.pi, 100))\n",
+    "\n",
+    "%matplotlib notebook\n",
+    "plt.figure(figsize=(5,5))\n",
+    "#plt.plot(np.array(filteredSorted)[:,0], np.array(filteredSorted)[:,1], 'r')\n",
+    "plt.plot(filterX,filterY,'b')\n",
+    "plt.plot(circx, circy)\n",
+    "plt.xlim([0.0125,0.2125])\n",
+    "plt.ylim([0.35,0.55])\n",
+    "rads = np.sqrt(filterX*filterX + filterY*filterY)\n",
+    "print(f\"Max radius: {np.max(rads)} at ({filterX[np.argmax(rads)]},{filterY[np.argmax(rads)]})\")\n",
+    "print(f\"Min radius: {np.min(rads)} at ({filterX[np.argmin(rads)]},{filterY[np.argmin(rads)]})\")\n",
+    "print(f\"Min x: {np.min(filterX)} at ({filterX[np.argmin(filterX)]},{filterY[np.argmin(filterX)]})\")\n",
+    "print(f\"Max x: {np.max(filterX)} at ({filterX[np.argmax(filterX)]},{filterY[np.argmax(filterX)]})\")\n",
+    "print(f\"Min y: {np.min(filterY)} at ({filterX[np.argmin(filterY)]},{filterY[np.argmin(filterY)]})\")\n",
+    "print(f\"Max y: {np.max(filterY)} at ({filterX[np.argmax(filterY)]},{filterY[np.argmax(filterY)]})\")\n",
+    "print(f\"Max Delta x: {np.max(filterX) - np.min(filterX)}\")\n",
+    "print(f\"Max Delta y: {np.max(filterY) - np.min(filterY)}\")\n",
+    "\n",
+    "print(f\"Points in old: {len(filterX)}\")\n",
+    "\n",
+    "a = (np.max(filterX) - np.min(filterX))/2.\n",
+    "b = (np.max(filterY) - np.min(filterY))/2.\n",
+    "cx = np.mean(filterX)\n",
+    "cy = np.mean(filterY)\n",
+    "ellx = cx + a * np.cos(np.linspace(0,2.*np.pi,100))\n",
+    "elly = cy + b * np.sin(np.linspace(0,2.*np.pi,100))\n",
+    "plt.plot(ellx,elly)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "np.savetxt('boundary.txt',np.transpose(np.array([filterX,filterY])))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Silicon Sample Design"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def rot(point_in, deg):\n",
+    "    point_out = [point_in[0], point_in[1]]\n",
+    "    rad = deg*np.pi/180.\n",
+    "    point_out[0] = point_in[0] * np.cos(rad) - point_in[1] * np.sin(rad)\n",
+    "    point_out[1] = point_in[0] * np.sin(rad) + point_in[1] * np.cos(rad)\n",
+    "    return point_out"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "filterXcomplete = []\n",
+    "filterYcomplete = []\n",
+    "for i in range(len(filterX)):\n",
+    "    filterXcomplete.append(filterX[i])\n",
+    "    filterYcomplete.append(filterY[i])\n",
+    "#angle = -3.*360./36.\n",
+    "angle = -360./7.3\n",
+    "for i in range(len(filterX)):\n",
+    "    p = rot([filterX[i],filterY[i]], angle)\n",
+    "    filterXcomplete.append(p[0])\n",
+    "    filterYcomplete.append(p[1])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Max arg: 63\n",
+      "Min arg: 18\n",
+      "Max distance from origin: [0.17676177423050082, 0.4684915868766098]\n",
+      "Min distance from origin: [0.036978412466203786, 0.44756655729109146]\n",
+      "18\n"
+     ]
+    }
+   ],
+   "source": [
+    "max_rad_arg = np.argmax(filterX**2+filterY**2)\n",
+    "min_rad_arg = np.argmin(filterX**2+filterY**2)\n",
+    "print(f\"Max arg: {max_rad_arg}\")\n",
+    "print(f\"Min arg: {min_rad_arg}\")\n",
+    "print(f\"Max distance from origin: [{filterX[max_rad_arg]}, {filterY[max_rad_arg]}]\")\n",
+    "print(f\"Min distance from origin: [{filterX[min_rad_arg]}, {filterY[min_rad_arg]}]\")\n",
+    "p_max = [filterX[max_rad_arg], filterY[max_rad_arg]]\n",
+    "p_min = [filterX[min_rad_arg], filterY[min_rad_arg]]\n",
+    "print(min_rad_arg)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAkAAAAJACAYAAABlmtk2AAAa9ElEQVR4Xu3WQQEAAAgCMelf2iA3GzB8sHMECBAgQIAAgZjAYnnFJUCAAAECBAicAeQJCBAgQIAAgZyAAZSrXGACBAgQIEDAAPIDBAgQIECAQE7AAMpVLjABAgQIECBgAPkBAgQIECBAICdgAOUqF5gAAQIECBAwgPwAAQIECBAgkBMwgHKVC0yAAAECBAgYQH6AAAECBAgQyAkYQLnKBSZAgAABAgQMID9AgAABAgQI5AQMoFzlAhMgQIAAAQIGkB8gQIAAAQIEcgIGUK5ygQkQIECAAAEDyA8QIECAAAECOQEDKFe5wAQIECBAgIAB5AcIECBAgACBnIABlKtcYAIECBAgQMAA8gMECBAgQIBATsAAylUuMAECBAgQIGAA+QECBAgQIEAgJ2AA5SoXmAABAgQIEDCA/AABAgQIECCQEzCAcpULTIAAAQIECBhAfoAAAQIECBDICRhAucoFJkCAAAECBAwgP0CAAAECBAjkBAygXOUCEyBAgAABAgaQHyBAgAABAgRyAgZQrnKBCRAgQIAAAQPIDxAgQIAAAQI5AQMoV7nABAgQIECAgAHkBwgQIECAAIGcgAGUq1xgAgQIECBAwADyAwQIECBAgEBOwADKVS4wAQIECBAgYAD5AQIECBAgQCAnYADlKheYAAECBAgQMID8AAECBAgQIJATMIBylQtMgAABAgQIGEB+gAABAgQIEMgJGEC5ygUmQIAAAQIEDCA/QIAAAQIECOQEDKBc5QITIECAAAECBpAfIECAAAECBHICBlCucoEJECBAgAABA8gPECBAgAABAjkBAyhXucAECBAgQICAAeQHCBAgQIAAgZyAAZSrXGACBAgQIEDAAPIDBAgQIECAQE7AAMpVLjABAgQIECBgAPkBAgQIECBAICdgAOUqF5gAAQIECBAwgPwAAQIECBAgkBMwgHKVC0yAAAECBAgYQH6AAAECBAgQyAkYQLnKBSZAgAABAgQMID9AgAABAgQI5AQMoFzlAhMgQIAAAQIGkB8gQIAAAQIEcgIGUK5ygQkQIECAAAEDyA8QIECAAAECOQEDKFe5wAQIECBAgIAB5AcIECBAgACBnIABlKtcYAIECBAgQMAA8gMECBAgQIBATsAAylUuMAECBAgQIGAA+QECBAgQIEAgJ2AA5SoXmAABAgQIEDCA/AABAgQIECCQEzCAcpULTIAAAQIECBhAfoAAAQIECBDICRhAucoFJkCAAAECBAwgP0CAAAECBAjkBAygXOUCEyBAgAABAgaQHyBAgAABAgRyAgZQrnKBCRAgQIAAAQPIDxAgQIAAAQI5AQMoV7nABAgQIECAgAHkBwgQIECAAIGcgAGUq1xgAgQIECBAwADyAwQIECBAgEBOwADKVS4wAQIECBAgYAD5AQIECBAgQCAnYADlKheYAAECBAgQMID8AAECBAgQIJATMIBylQtMgAABAgQIGEB+gAABAgQIEMgJGEC5ygUmQIAAAQIEDCA/QIAAAQIECOQEDKBc5QITIECAAAECBpAfIECAAAECBHICBlCucoEJECBAgAABA8gPECBAgAABAjkBAyhXucAECBAgQICAAeQHCBAgQIAAgZyAAZSrXGACBAgQIEDAAPIDBAgQIECAQE7AAMpVLjABAgQIECBgAPkBAgQIECBAICdgAOUqF5gAAQIECBAwgPwAAQIECBAgkBMwgHKVC0yAAAECBAgYQH6AAAECBAgQyAkYQLnKBSZAgAABAgQMID9AgAABAgQI5AQMoFzlAhMgQIAAAQIGkB8gQIAAAQIEcgIGUK5ygQkQIECAAAEDyA8QIECAAAECOQEDKFe5wAQIECBAgIAB5AcIECBAgACBnIABlKtcYAIECBAgQMAA8gMECBAgQIBATsAAylUuMAECBAgQIGAA+QECBAgQIEAgJ2AA5SoXmAABAgQIEDCA/AABAgQIECCQEzCAcpULTIAAAQIECBhAfoAAAQIECBDICRhAucoFJkCAAAECBAwgP0CAAAECBAjkBAygXOUCEyBAgAABAgaQHyBAgAABAgRyAgZQrnKBCRAgQIAAAQPIDxAgQIAAAQI5AQMoV7nABAgQIECAgAHkBwgQIECAAIGcgAGUq1xgAgQIECBAwADyAwQIECBAgEBOwADKVS4wAQIECBAgYAD5AQIECBAgQCAnYADlKheYAAECBAgQMID8AAECBAgQIJATMIBylQtMgAABAgQIGEB+gAABAgQIEMgJGEC5ygUmQIAAAQIEDCA/QIAAAQIECOQEDKBc5QITIECAAAECBpAfIECAAAECBHICBlCucoEJECBAgAABA8gPECBAgAABAjkBAyhXucAECBAgQICAAeQHCBAgQIAAgZyAAZSrXGACBAgQIEDAAPIDBAgQIECAQE7AAMpVLjABAgQIECBgAPkBAgQIECBAICdgAOUqF5gAAQIECBAwgPwAAQIECBAgkBMwgHKVC0yAAAECBAgYQH6AAAECBAgQyAkYQLnKBSZAgAABAgQMID9AgAABAgQI5AQMoFzlAhMgQIAAAQIGkB8gQIAAAQIEcgIGUK5ygQkQIECAAAEDyA8QIECAAAECOQEDKFe5wAQIECBAgIAB5AcIECBAgACBnIABlKtcYAIECBAgQMAA8gMECBAgQIBATsAAylUuMAECBAgQIGAA+QECBAgQIEAgJ2AA5SoXmAABAgQIEDCA/AABAgQIECCQEzCAcpULTIAAAQIECBhAfoAAAQIECBDICRhAucoFJkCAAAECBAwgP0CAAAECBAjkBAygXOUCEyBAgAABAgaQHyBAgAABAgRyAgZQrnKBCRAgQIAAAQPIDxAgQIAAAQI5AQMoV7nABAgQIECAgAHkBwgQIECAAIGcgAGUq1xgAgQIECBAwADyAwQIECBAgEBOwADKVS4wAQIECBAgYAD5AQIECBAgQCAnYADlKheYAAECBAgQMID8AAECBAgQIJATMIBylQtMgAABAgQIGEB+gAABAgQIEMgJGEC5ygUmQIAAAQIEDCA/QIAAAQIECOQEDKBc5QITIECAAAECBpAfIECAAAECBHICBlCucoEJECBAgAABA8gPECBAgAABAjkBAyhXucAECBAgQICAAeQHCBAgQIAAgZyAAZSrXGACBAgQIEDAAPIDBAgQIECAQE7AAMpVLjABAgQIECBgAPkBAgQIECBAICdgAOUqF5gAAQIECBAwgPwAAQIECBAgkBMwgHKVC0yAAAECBAgYQH6AAAECBAgQyAkYQLnKBSZAgAABAgQMID9AgAABAgQI5AQMoFzlAhMgQIAAAQIGkB8gQIAAAQIEcgIGUK5ygQkQIECAAAEDyA8QIECAAAECOQEDKFe5wAQIECBAgIAB5AcIECBAgACBnIABlKtcYAIECBAgQMAA8gMECBAgQIBATsAAylUuMAECBAgQIGAA+QECBAgQIEAgJ2AA5SoXmAABAgQIEDCA/AABAgQIECCQEzCAcpULTIAAAQIECBhAfoAAAQIECBDICRhAucoFJkCAAAECBAwgP0CAAAECBAjkBAygXOUCEyBAgAABAgaQHyBAgAABAgRyAgZQrnKBCRAgQIAAAQPIDxAgQIAAAQI5AQMoV7nABAgQIECAgAHkBwgQIECAAIGcgAGUq1xgAgQIECBAwADyAwQIECBAgEBOwADKVS4wAQIECBAgYAD5AQIECBAgQCAnYADlKheYAAECBAgQMID8AAECBAgQIJATMIBylQtMgAABAgQIGEB+gAABAgQIEMgJGEC5ygUmQIAAAQIEDCA/QIAAAQIECOQEDKBc5QITIECAAAECBpAfIECAAAECBHICBlCucoEJECBAgAABA8gPECBAgAABAjkBAyhXucAECBAgQICAAeQHCBAgQIAAgZyAAZSrXGACBAgQIEDAAPIDBAgQIECAQE7AAMpVLjABAgQIECBgAPkBAgQIECBAICdgAOUqF5gAAQIECBAwgPwAAQIECBAgkBMwgHKVC0yAAAECBAgYQH6AAAECBAgQyAkYQLnKBSZAgAABAgQMID9AgAABAgQI5AQMoFzlAhMgQIAAAQIGkB8gQIAAAQIEcgIGUK5ygQkQIECAAAEDyA8QIECAAAECOQEDKFe5wAQIECBAgIAB5AcIECBAgACBnIABlKtcYAIECBAgQMAA8gMECBAgQIBATsAAylUuMAECBAgQIGAA+QECBAgQIEAgJ2AA5SoXmAABAgQIEDCA/AABAgQIECCQEzCAcpULTIAAAQIECBhAfoAAAQIECBDICRhAucoFJkCAAAECBAwgP0CAAAECBAjkBAygXOUCEyBAgAABAgaQHyBAgAABAgRyAgZQrnKBCRAgQIAAAQPIDxAgQIAAAQI5AQMoV7nABAgQIECAgAHkBwgQIECAAIGcgAGUq1xgAgQIECBAwADyAwQIECBAgEBOwADKVS4wAQIECBAgYAD5AQIECBAgQCAnYADlKheYAAECBAgQMID8AAECBAgQIJATMIBylQtMgAABAgQIGEB+gAABAgQIEMgJGEC5ygUmQIAAAQIEDCA/QIAAAQIECOQEDKBc5QITIECAAAECBpAfIECAAAECBHICBlCucoEJECBAgAABA8gPECBAgAABAjkBAyhXucAECBAgQICAAeQHCBAgQIAAgZyAAZSrXGACBAgQIEDAAPIDBAgQIECAQE7AAMpVLjABAgQIECBgAPkBAgQIECBAICdgAOUqF5gAAQIECBAwgPwAAQIECBAgkBMwgHKVC0yAAAECBAgYQH6AAAECBAgQyAkYQLnKBSZAgAABAgQMID9AgAABAgQI5AQMoFzlAhMgQIAAAQIGkB8gQIAAAQIEcgIGUK5ygQkQIECAAAEDyA8QIECAAAECOQEDKFe5wAQIECBAgIAB5AcIECBAgACBnIABlKtcYAIECBAgQMAA8gMECBAgQIBATsAAylUuMAECBAgQIGAA+QECBAgQIEAgJ2AA5SoXmAABAgQIEDCA/AABAgQIECCQEzCAcpULTIAAAQIECBhAfoAAAQIECBDICRhAucoFJkCAAAECBAwgP0CAAAECBAjkBAygXOUCEyBAgAABAgaQHyBAgAABAgRyAgZQrnKBCRAgQIAAAQPIDxAgQIAAAQI5AQMoV7nABAgQIECAgAHkBwgQIECAAIGcgAGUq1xgAgQIECBAwADyAwQIECBAgEBOwADKVS4wAQIECBAgYAD5AQIECBAgQCAnYADlKheYAAECBAgQMID8AAECBAgQIJATMIBylQtMgAABAgQIGEB+gAABAgQIEMgJGEC5ygUmQIAAAQIEDCA/QIAAAQIECOQEDKBc5QITIECAAAECBpAfIECAAAECBHICBlCucoEJECBAgAABA8gPECBAgAABAjkBAyhXucAECBAgQICAAeQHCBAgQIAAgZyAAZSrXGACBAgQIEDAAPIDBAgQIECAQE7AAMpVLjABAgQIECBgAPkBAgQIECBAICdgAOUqF5gAAQIECBAwgPwAAQIECBAgkBMwgHKVC0yAAAECBAgYQH6AAAECBAgQyAkYQLnKBSZAgAABAgQMID9AgAABAgQI5AQMoFzlAhMgQIAAAQIGkB8gQIAAAQIEcgIGUK5ygQkQIECAAAEDyA8QIECAAAECOQEDKFe5wAQIECBAgIAB5AcIECBAgACBnIABlKtcYAIECBAgQMAA8gMECBAgQIBATsAAylUuMAECBAgQIGAA+QECBAgQIEAgJ2AA5SoXmAABAgQIEDCA/AABAgQIECCQEzCAcpULTIAAAQIECBhAfoAAAQIECBDICRhAucoFJkCAAAECBAwgP0CAAAECBAjkBAygXOUCEyBAgAABAgaQHyBAgAABAgRyAgZQrnKBCRAgQIAAAQPIDxAgQIAAAQI5AQMoV7nABAgQIECAgAHkBwgQIECAAIGcgAGUq1xgAgQIECBAwADyAwQIECBAgEBOwADKVS4wAQIECBAgYAD5AQIECBAgQCAnYADlKheYAAECBAgQMID8AAECBAgQIJATMIBylQtMgAABAgQIGEB+gAABAgQIEMgJGEC5ygUmQIAAAQIEDCA/QIAAAQIECOQEDKBc5QITIECAAAECBpAfIECAAAECBHICBlCucoEJECBAgAABA8gPECBAgAABAjkBAyhXucAECBAgQICAAeQHCBAgQIAAgZyAAZSrXGACBAgQIEDAAPIDBAgQIECAQE7AAMpVLjABAgQIECBgAPkBAgQIECBAICdgAOUqF5gAAQIECBAwgPwAAQIECBAgkBMwgHKVC0yAAAECBAgYQH6AAAECBAgQyAkYQLnKBSZAgAABAgQMID9AgAABAgQI5AQMoFzlAhMgQIAAAQIGkB8gQIAAAQIEcgIGUK5ygQkQIECAAAEDyA8QIECAAAECOQEDKFe5wAQIECBAgIAB5AcIECBAgACBnIABlKtcYAIECBAgQMAA8gMECBAgQIBATsAAylUuMAECBAgQIGAA+QECBAgQIEAgJ2AA5SoXmAABAgQIEDCA/AABAgQIECCQEzCAcpULTIAAAQIECBhAfoAAAQIECBDICRhAucoFJkCAAAECBAwgP0CAAAECBAjkBAygXOUCEyBAgAABAgaQHyBAgAABAgRyAgZQrnKBCRAgQIAAAQPIDxAgQIAAAQI5AQMoV7nABAgQIECAgAHkBwgQIECAAIGcgAGUq1xgAgQIECBAwADyAwQIECBAgEBOwADKVS4wAQIECBAgYAD5AQIECBAgQCAnYADlKheYAAECBAgQMID8AAECBAgQIJATMIBylQtMgAABAgQIGEB+gAABAgQIEMgJGEC5ygUmQIAAAQIEDCA/QIAAAQIECOQEDKBc5QITIECAAAECBpAfIECAAAECBHICBlCucoEJECBAgAABA8gPECBAgAABAjkBAyhXucAECBAgQICAAeQHCBAgQIAAgZyAAZSrXGACBAgQIEDAAPIDBAgQIECAQE7AAMpVLjABAgQIECBgAPkBAgQIECBAICdgAOUqF5gAAQIECBAwgPwAAQIECBAgkBMwgHKVC0yAAAECBAgYQH6AAAECBAgQyAkYQLnKBSZAgAABAgQMID9AgAABAgQI5AQMoFzlAhMgQIAAAQIGkB8gQIAAAQIEcgIGUK5ygQkQIECAAAEDyA8QIECAAAECOQEDKFe5wAQIECBAgIAB5AcIECBAgACBnIABlKtcYAIECBAgQMAA8gMECBAgQIBATsAAylUuMAECBAgQIGAA+QECBAgQIEAgJ2AA5SoXmAABAgQIEDCA/AABAgQIECCQEzCAcpULTIAAAQIECBhAfoAAAQIECBDICRhAucoFJkCAAAECBAwgP0CAAAECBAjkBAygXOUCEyBAgAABAgaQHyBAgAABAgRyAgZQrnKBCRAgQIAAAQPIDxAgQIAAAQI5AQMoV7nABAgQIECAgAHkBwgQIECAAIGcgAGUq1xgAgQIECBAwADyAwQIECBAgEBOwADKVS4wAQIECBAgYAD5AQIECBAgQCAnYADlKheYAAECBAgQMID8AAECBAgQIJATMIBylQtMgAABAgQIGEB+gAABAgQIEMgJGEC5ygUmQIAAAQIEDCA/QIAAAQIECOQEDKBc5QITIECAAAECBpAfIECAAAECBHICBlCucoEJECBAgAABA8gPECBAgAABAjkBAyhXucAECBAgQICAAeQHCBAgQIAAgZyAAZSrXGACBAgQIEDAAPIDBAgQIECAQE7AAMpVLjABAgQIECBgAPkBAgQIECBAICdgAOUqF5gAAQIECBAwgPwAAQIECBAgkBMwgHKVC0yAAAECBAgYQH6AAAECBAgQyAkYQLnKBSZAgAABAgQMID9AgAABAgQI5AQMoFzlAhMgQIAAAQIGkB8gQIAAAQIEcgIGUK5ygQkQIECAAAEDyA8QIECAAAECOQEDKFe5wAQIECBAgIAB5AcIECBAgACBnIABlKtcYAIECBAgQMAA8gMECBAgQIBATsAAylUuMAECBAgQIGAA+QECBAgQIEAgJ2AA5SoXmAABAgQIEDCA/AABAgQIECCQEzCAcpULTIAAAQIECBhAfoAAAQIECBDICRhAucoFJkCAAAECBAwgP0CAAAECBAjkBAygXOUCEyBAgAABAgaQHyBAgAABAgRyAgZQrnKBCRAgQIAAAQPIDxAgQIAAAQI5AQMoV7nABAgQIECAgAHkBwgQIECAAIGcgAGUq1xgAgQIECBAwADyAwQIECBAgEBOwADKVS4wAQIECBAgYAD5AQIECBAgQCAnYADlKheYAAECBAgQMID8AAECBAgQIJATMIBylQtMgAABAgQIGEB+gAABAgQIEMgJGEC5ygUmQIAAAQIEDCA/QIAAAQIECOQEDKBc5QITIECAAAECBpAfIECAAAECBHICBlCucoEJECBAgAABA8gPECBAgAABAjkBAyhXucAECBAgQICAAeQHCBAgQIAAgZyAAZSrXGACBAgQIEDAAPIDBAgQIECAQE7AAMpVLjABAgQIECBgAPkBAgQIECBAICdgAOUqF5gAAQIECBAwgPwAAQIECBAgkBMwgHKVC0yAAAECBAgYQH6AAAECBAgQyAkYQLnKBSZAgAABAgQMID9AgAABAgQI5AQMoFzlAhMgQIAAAQIGkB8gQIAAAQIEcgIGUK5ygQkQIECAAAEDyA8QIECAAAECOQEDKFe5wAQIECBAgIAB5AcIECBAgACBnIABlKtcYAIECBAgQMAA8gMECBAgQIBATsAAylUuMAECBAgQIGAA+QECBAgQIEAgJ2AA5SoXmAABAgQIEDCA/AABAgQIECCQEzCAcpULTIAAAQIECBhAfoAAAQIECBDICRhAucoFJkCAAAECBAwgP0CAAAECBAjkBAygXOUCEyBAgAABAgaQHyBAgAABAgRyAgZQrnKBCRAgQIAAAQPIDxAgQIAAAQI5AQMoV7nABAgQIECAgAHkBwgQIECAAIGcgAGUq1xgAgQIECBAwADyAwQIECBAgEBOwADKVS4wAQIECBAgYAD5AQIECBAgQCAnYADlKheYAAECBAgQMID8AAECBAgQIJATMIBylQtMgAABAgQIGEB+gAABAgQIEMgJGEC5ygUmQIAAAQIEDCA/QIAAAQIECOQEDKBc5QITIECAAAECBpAfIECAAAECBHICBlCucoEJECBAgACBB0MWAkEc/naKAAAAAElFTkSuQmCC\" width=\"576\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "(-0.5, 0.5)"
+      ]
+     },
+     "execution_count": 25,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "plt.figure(figsize=(8,8))\n",
+    "plt.plot(filterXcomplete,filterYcomplete,'b')\n",
+    "plt.plot([p_max[0]], [p_max[1]], '*', c='r')\n",
+    "plt.plot([p_min[0]], [p_min[1]], '*', c='r')\n",
+    "plt.plot([filterXcomplete[40]], [filterYcomplete[40]], '*', c='g')\n",
+    "plt.xlim([-0.5,0.5])\n",
+    "plt.ylim([-0.5,0.5])"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Strategy:\n",
+    "\n",
+    "For the unrotated hole, keep all points with indices in [0,min] or [max, len].\n",
+    "\n",
+    "For the rotated hole, keep all points with indices in [min, max]."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#assemble arcs\n",
+    "Rinner = np.sqrt(p_min[0]**2 + p_min[1]**2)\n",
+    "Router = np.sqrt(p_max[0]**2 + p_max[1]**2)\n",
+    "arcInnerX = []\n",
+    "arcInnerY = []\n",
+    "arcOuterX = []\n",
+    "arcOuterY = []\n",
+    "\n",
+    "arcSegments = 50.\n",
+    "for n in range(int(arcSegments)):\n",
+    "    pinner = rot(p_min, n*angle/arcSegments)\n",
+    "    arcInnerX.append(pinner[0])\n",
+    "    arcInnerY.append(pinner[1])\n",
+    "    pouter = rot(rot(p_max, angle), -n*angle/arcSegments)\n",
+    "    arcOuterX.append(pouter[0])\n",
+    "    arcOuterY.append(pouter[1])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#assemble final hole\n",
+    "finalHoleX = []\n",
+    "finalHoleY = []\n",
+    "for i in range(min_rad_arg):\n",
+    "    finalHoleX.append(filterXcomplete[i])\n",
+    "    finalHoleY.append(filterYcomplete[i])\n",
+    "for i in range(len(arcInnerX)):\n",
+    "    finalHoleX.append(arcInnerX[i])\n",
+    "    finalHoleY.append(arcInnerY[i])\n",
+    "for i in range(min_rad_arg+1+len(filterX), max_rad_arg+len(filterX)):\n",
+    "    finalHoleX.append(filterXcomplete[i])\n",
+    "    finalHoleY.append(filterYcomplete[i])\n",
+    "for i in range(len(arcOuterX)):\n",
+    "    finalHoleX.append(arcOuterX[i])\n",
+    "    finalHoleY.append(arcOuterY[i])\n",
+    "for i in range(max_rad_arg+1, len(filterX)):\n",
+    "    finalHoleX.append(filterXcomplete[i])\n",
+    "    finalHoleY.append(filterYcomplete[i])\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAkAAAAJACAYAAABlmtk2AAAa9ElEQVR4Xu3WQQEAAAgCMelf2iA3GzB8sHMECBAgQIAAgZjAYnnFJUCAAAECBAicAeQJCBAgQIAAgZyAAZSrXGACBAgQIEDAAPIDBAgQIECAQE7AAMpVLjABAgQIECBgAPkBAgQIECBAICdgAOUqF5gAAQIECBAwgPwAAQIECBAgkBMwgHKVC0yAAAECBAgYQH6AAAECBAgQyAkYQLnKBSZAgAABAgQMID9AgAABAgQI5AQMoFzlAhMgQIAAAQIGkB8gQIAAAQIEcgIGUK5ygQkQIECAAAEDyA8QIECAAAECOQEDKFe5wAQIECBAgIAB5AcIECBAgACBnIABlKtcYAIECBAgQMAA8gMECBAgQIBATsAAylUuMAECBAgQIGAA+QECBAgQIEAgJ2AA5SoXmAABAgQIEDCA/AABAgQIECCQEzCAcpULTIAAAQIECBhAfoAAAQIECBDICRhAucoFJkCAAAECBAwgP0CAAAECBAjkBAygXOUCEyBAgAABAgaQHyBAgAABAgRyAgZQrnKBCRAgQIAAAQPIDxAgQIAAAQI5AQMoV7nABAgQIECAgAHkBwgQIECAAIGcgAGUq1xgAgQIECBAwADyAwQIECBAgEBOwADKVS4wAQIECBAgYAD5AQIECBAgQCAnYADlKheYAAECBAgQMID8AAECBAgQIJATMIBylQtMgAABAgQIGEB+gAABAgQIEMgJGEC5ygUmQIAAAQIEDCA/QIAAAQIECOQEDKBc5QITIECAAAECBpAfIECAAAECBHICBlCucoEJECBAgAABA8gPECBAgAABAjkBAyhXucAECBAgQICAAeQHCBAgQIAAgZyAAZSrXGACBAgQIEDAAPIDBAgQIECAQE7AAMpVLjABAgQIECBgAPkBAgQIECBAICdgAOUqF5gAAQIECBAwgPwAAQIECBAgkBMwgHKVC0yAAAECBAgYQH6AAAECBAgQyAkYQLnKBSZAgAABAgQMID9AgAABAgQI5AQMoFzlAhMgQIAAAQIGkB8gQIAAAQIEcgIGUK5ygQkQIECAAAEDyA8QIECAAAECOQEDKFe5wAQIECBAgIAB5AcIECBAgACBnIABlKtcYAIECBAgQMAA8gMECBAgQIBATsAAylUuMAECBAgQIGAA+QECBAgQIEAgJ2AA5SoXmAABAgQIEDCA/AABAgQIECCQEzCAcpULTIAAAQIECBhAfoAAAQIECBDICRhAucoFJkCAAAECBAwgP0CAAAECBAjkBAygXOUCEyBAgAABAgaQHyBAgAABAgRyAgZQrnKBCRAgQIAAAQPIDxAgQIAAAQI5AQMoV7nABAgQIECAgAHkBwgQIECAAIGcgAGUq1xgAgQIECBAwADyAwQIECBAgEBOwADKVS4wAQIECBAgYAD5AQIECBAgQCAnYADlKheYAAECBAgQMID8AAECBAgQIJATMIBylQtMgAABAgQIGEB+gAABAgQIEMgJGEC5ygUmQIAAAQIEDCA/QIAAAQIECOQEDKBc5QITIECAAAECBpAfIECAAAECBHICBlCucoEJECBAgAABA8gPECBAgAABAjkBAyhXucAECBAgQICAAeQHCBAgQIAAgZyAAZSrXGACBAgQIEDAAPIDBAgQIECAQE7AAMpVLjABAgQIECBgAPkBAgQIECBAICdgAOUqF5gAAQIECBAwgPwAAQIECBAgkBMwgHKVC0yAAAECBAgYQH6AAAECBAgQyAkYQLnKBSZAgAABAgQMID9AgAABAgQI5AQMoFzlAhMgQIAAAQIGkB8gQIAAAQIEcgIGUK5ygQkQIECAAAEDyA8QIECAAAECOQEDKFe5wAQIECBAgIAB5AcIECBAgACBnIABlKtcYAIECBAgQMAA8gMECBAgQIBATsAAylUuMAECBAgQIGAA+QECBAgQIEAgJ2AA5SoXmAABAgQIEDCA/AABAgQIECCQEzCAcpULTIAAAQIECBhAfoAAAQIECBDICRhAucoFJkCAAAECBAwgP0CAAAECBAjkBAygXOUCEyBAgAABAgaQHyBAgAABAgRyAgZQrnKBCRAgQIAAAQPIDxAgQIAAAQI5AQMoV7nABAgQIECAgAHkBwgQIECAAIGcgAGUq1xgAgQIECBAwADyAwQIECBAgEBOwADKVS4wAQIECBAgYAD5AQIECBAgQCAnYADlKheYAAECBAgQMID8AAECBAgQIJATMIBylQtMgAABAgQIGEB+gAABAgQIEMgJGEC5ygUmQIAAAQIEDCA/QIAAAQIECOQEDKBc5QITIECAAAECBpAfIECAAAECBHICBlCucoEJECBAgAABA8gPECBAgAABAjkBAyhXucAECBAgQICAAeQHCBAgQIAAgZyAAZSrXGACBAgQIEDAAPIDBAgQIECAQE7AAMpVLjABAgQIECBgAPkBAgQIECBAICdgAOUqF5gAAQIECBAwgPwAAQIECBAgkBMwgHKVC0yAAAECBAgYQH6AAAECBAgQyAkYQLnKBSZAgAABAgQMID9AgAABAgQI5AQMoFzlAhMgQIAAAQIGkB8gQIAAAQIEcgIGUK5ygQkQIECAAAEDyA8QIECAAAECOQEDKFe5wAQIECBAgIAB5AcIECBAgACBnIABlKtcYAIECBAgQMAA8gMECBAgQIBATsAAylUuMAECBAgQIGAA+QECBAgQIEAgJ2AA5SoXmAABAgQIEDCA/AABAgQIECCQEzCAcpULTIAAAQIECBhAfoAAAQIECBDICRhAucoFJkCAAAECBAwgP0CAAAECBAjkBAygXOUCEyBAgAABAgaQHyBAgAABAgRyAgZQrnKBCRAgQIAAAQPIDxAgQIAAAQI5AQMoV7nABAgQIECAgAHkBwgQIECAAIGcgAGUq1xgAgQIECBAwADyAwQIECBAgEBOwADKVS4wAQIECBAgYAD5AQIECBAgQCAnYADlKheYAAECBAgQMID8AAECBAgQIJATMIBylQtMgAABAgQIGEB+gAABAgQIEMgJGEC5ygUmQIAAAQIEDCA/QIAAAQIECOQEDKBc5QITIECAAAECBpAfIECAAAECBHICBlCucoEJECBAgAABA8gPECBAgAABAjkBAyhXucAECBAgQICAAeQHCBAgQIAAgZyAAZSrXGACBAgQIEDAAPIDBAgQIECAQE7AAMpVLjABAgQIECBgAPkBAgQIECBAICdgAOUqF5gAAQIECBAwgPwAAQIECBAgkBMwgHKVC0yAAAECBAgYQH6AAAECBAgQyAkYQLnKBSZAgAABAgQMID9AgAABAgQI5AQMoFzlAhMgQIAAAQIGkB8gQIAAAQIEcgIGUK5ygQkQIECAAAEDyA8QIECAAAECOQEDKFe5wAQIECBAgIAB5AcIECBAgACBnIABlKtcYAIECBAgQMAA8gMECBAgQIBATsAAylUuMAECBAgQIGAA+QECBAgQIEAgJ2AA5SoXmAABAgQIEDCA/AABAgQIECCQEzCAcpULTIAAAQIECBhAfoAAAQIECBDICRhAucoFJkCAAAECBAwgP0CAAAECBAjkBAygXOUCEyBAgAABAgaQHyBAgAABAgRyAgZQrnKBCRAgQIAAAQPIDxAgQIAAAQI5AQMoV7nABAgQIECAgAHkBwgQIECAAIGcgAGUq1xgAgQIECBAwADyAwQIECBAgEBOwADKVS4wAQIECBAgYAD5AQIECBAgQCAnYADlKheYAAECBAgQMID8AAECBAgQIJATMIBylQtMgAABAgQIGEB+gAABAgQIEMgJGEC5ygUmQIAAAQIEDCA/QIAAAQIECOQEDKBc5QITIECAAAECBpAfIECAAAECBHICBlCucoEJECBAgAABA8gPECBAgAABAjkBAyhXucAECBAgQICAAeQHCBAgQIAAgZyAAZSrXGACBAgQIEDAAPIDBAgQIECAQE7AAMpVLjABAgQIECBgAPkBAgQIECBAICdgAOUqF5gAAQIECBAwgPwAAQIECBAgkBMwgHKVC0yAAAECBAgYQH6AAAECBAgQyAkYQLnKBSZAgAABAgQMID9AgAABAgQI5AQMoFzlAhMgQIAAAQIGkB8gQIAAAQIEcgIGUK5ygQkQIECAAAEDyA8QIECAAAECOQEDKFe5wAQIECBAgIAB5AcIECBAgACBnIABlKtcYAIECBAgQMAA8gMECBAgQIBATsAAylUuMAECBAgQIGAA+QECBAgQIEAgJ2AA5SoXmAABAgQIEDCA/AABAgQIECCQEzCAcpULTIAAAQIECBhAfoAAAQIECBDICRhAucoFJkCAAAECBAwgP0CAAAECBAjkBAygXOUCEyBAgAABAgaQHyBAgAABAgRyAgZQrnKBCRAgQIAAAQPIDxAgQIAAAQI5AQMoV7nABAgQIECAgAHkBwgQIECAAIGcgAGUq1xgAgQIECBAwADyAwQIECBAgEBOwADKVS4wAQIECBAgYAD5AQIECBAgQCAnYADlKheYAAECBAgQMID8AAECBAgQIJATMIBylQtMgAABAgQIGEB+gAABAgQIEMgJGEC5ygUmQIAAAQIEDCA/QIAAAQIECOQEDKBc5QITIECAAAECBpAfIECAAAECBHICBlCucoEJECBAgAABA8gPECBAgAABAjkBAyhXucAECBAgQICAAeQHCBAgQIAAgZyAAZSrXGACBAgQIEDAAPIDBAgQIECAQE7AAMpVLjABAgQIECBgAPkBAgQIECBAICdgAOUqF5gAAQIECBAwgPwAAQIECBAgkBMwgHKVC0yAAAECBAgYQH6AAAECBAgQyAkYQLnKBSZAgAABAgQMID9AgAABAgQI5AQMoFzlAhMgQIAAAQIGkB8gQIAAAQIEcgIGUK5ygQkQIECAAAEDyA8QIECAAAECOQEDKFe5wAQIECBAgIAB5AcIECBAgACBnIABlKtcYAIECBAgQMAA8gMECBAgQIBATsAAylUuMAECBAgQIGAA+QECBAgQIEAgJ2AA5SoXmAABAgQIEDCA/AABAgQIECCQEzCAcpULTIAAAQIECBhAfoAAAQIECBDICRhAucoFJkCAAAECBAwgP0CAAAECBAjkBAygXOUCEyBAgAABAgaQHyBAgAABAgRyAgZQrnKBCRAgQIAAAQPIDxAgQIAAAQI5AQMoV7nABAgQIECAgAHkBwgQIECAAIGcgAGUq1xgAgQIECBAwADyAwQIECBAgEBOwADKVS4wAQIECBAgYAD5AQIECBAgQCAnYADlKheYAAECBAgQMID8AAECBAgQIJATMIBylQtMgAABAgQIGEB+gAABAgQIEMgJGEC5ygUmQIAAAQIEDCA/QIAAAQIECOQEDKBc5QITIECAAAECBpAfIECAAAECBHICBlCucoEJECBAgAABA8gPECBAgAABAjkBAyhXucAECBAgQICAAeQHCBAgQIAAgZyAAZSrXGACBAgQIEDAAPIDBAgQIECAQE7AAMpVLjABAgQIECBgAPkBAgQIECBAICdgAOUqF5gAAQIECBAwgPwAAQIECBAgkBMwgHKVC0yAAAECBAgYQH6AAAECBAgQyAkYQLnKBSZAgAABAgQMID9AgAABAgQI5AQMoFzlAhMgQIAAAQIGkB8gQIAAAQIEcgIGUK5ygQkQIECAAAEDyA8QIECAAAECOQEDKFe5wAQIECBAgIAB5AcIECBAgACBnIABlKtcYAIECBAgQMAA8gMECBAgQIBATsAAylUuMAECBAgQIGAA+QECBAgQIEAgJ2AA5SoXmAABAgQIEDCA/AABAgQIECCQEzCAcpULTIAAAQIECBhAfoAAAQIECBDICRhAucoFJkCAAAECBAwgP0CAAAECBAjkBAygXOUCEyBAgAABAgaQHyBAgAABAgRyAgZQrnKBCRAgQIAAAQPIDxAgQIAAAQI5AQMoV7nABAgQIECAgAHkBwgQIECAAIGcgAGUq1xgAgQIECBAwADyAwQIECBAgEBOwADKVS4wAQIECBAgYAD5AQIECBAgQCAnYADlKheYAAECBAgQMID8AAECBAgQIJATMIBylQtMgAABAgQIGEB+gAABAgQIEMgJGEC5ygUmQIAAAQIEDCA/QIAAAQIECOQEDKBc5QITIECAAAECBpAfIECAAAECBHICBlCucoEJECBAgAABA8gPECBAgAABAjkBAyhXucAECBAgQICAAeQHCBAgQIAAgZyAAZSrXGACBAgQIEDAAPIDBAgQIECAQE7AAMpVLjABAgQIECBgAPkBAgQIECBAICdgAOUqF5gAAQIECBAwgPwAAQIECBAgkBMwgHKVC0yAAAECBAgYQH6AAAECBAgQyAkYQLnKBSZAgAABAgQMID9AgAABAgQI5AQMoFzlAhMgQIAAAQIGkB8gQIAAAQIEcgIGUK5ygQkQIECAAAEDyA8QIECAAAECOQEDKFe5wAQIECBAgIAB5AcIECBAgACBnIABlKtcYAIECBAgQMAA8gMECBAgQIBATsAAylUuMAECBAgQIGAA+QECBAgQIEAgJ2AA5SoXmAABAgQIEDCA/AABAgQIECCQEzCAcpULTIAAAQIECBhAfoAAAQIECBDICRhAucoFJkCAAAECBAwgP0CAAAECBAjkBAygXOUCEyBAgAABAgaQHyBAgAABAgRyAgZQrnKBCRAgQIAAAQPIDxAgQIAAAQI5AQMoV7nABAgQIECAgAHkBwgQIECAAIGcgAGUq1xgAgQIECBAwADyAwQIECBAgEBOwADKVS4wAQIECBAgYAD5AQIECBAgQCAnYADlKheYAAECBAgQMID8AAECBAgQIJATMIBylQtMgAABAgQIGEB+gAABAgQIEMgJGEC5ygUmQIAAAQIEDCA/QIAAAQIECOQEDKBc5QITIECAAAECBpAfIECAAAECBHICBlCucoEJECBAgAABA8gPECBAgAABAjkBAyhXucAECBAgQICAAeQHCBAgQIAAgZyAAZSrXGACBAgQIEDAAPIDBAgQIECAQE7AAMpVLjABAgQIECBgAPkBAgQIECBAICdgAOUqF5gAAQIECBAwgPwAAQIECBAgkBMwgHKVC0yAAAECBAgYQH6AAAECBAgQyAkYQLnKBSZAgAABAgQMID9AgAABAgQI5AQMoFzlAhMgQIAAAQIGkB8gQIAAAQIEcgIGUK5ygQkQIECAAAEDyA8QIECAAAECOQEDKFe5wAQIECBAgIAB5AcIECBAgACBnIABlKtcYAIECBAgQMAA8gMECBAgQIBATsAAylUuMAECBAgQIGAA+QECBAgQIEAgJ2AA5SoXmAABAgQIEDCA/AABAgQIECCQEzCAcpULTIAAAQIECBhAfoAAAQIECBDICRhAucoFJkCAAAECBAwgP0CAAAECBAjkBAygXOUCEyBAgAABAgaQHyBAgAABAgRyAgZQrnKBCRAgQIAAAQPIDxAgQIAAAQI5AQMoV7nABAgQIECAgAHkBwgQIECAAIGcgAGUq1xgAgQIECBAwADyAwQIECBAgEBOwADKVS4wAQIECBAgYAD5AQIECBAgQCAnYADlKheYAAECBAgQMID8AAECBAgQIJATMIBylQtMgAABAgQIGEB+gAABAgQIEMgJGEC5ygUmQIAAAQIEDCA/QIAAAQIECOQEDKBc5QITIECAAAECBpAfIECAAAECBHICBlCucoEJECBAgAABA8gPECBAgAABAjkBAyhXucAECBAgQICAAeQHCBAgQIAAgZyAAZSrXGACBAgQIEDAAPIDBAgQIECAQE7AAMpVLjABAgQIECBgAPkBAgQIECBAICdgAOUqF5gAAQIECBAwgPwAAQIECBAgkBMwgHKVC0yAAAECBAgYQH6AAAECBAgQyAkYQLnKBSZAgAABAgQMID9AgAABAgQI5AQMoFzlAhMgQIAAAQIGkB8gQIAAAQIEcgIGUK5ygQkQIECAAAEDyA8QIECAAAECOQEDKFe5wAQIECBAgIAB5AcIECBAgACBnIABlKtcYAIECBAgQMAA8gMECBAgQIBATsAAylUuMAECBAgQIGAA+QECBAgQIEAgJ2AA5SoXmAABAgQIEDCA/AABAgQIECCQEzCAcpULTIAAAQIECBhAfoAAAQIECBDICRhAucoFJkCAAAECBAwgP0CAAAECBAjkBAygXOUCEyBAgAABAgaQHyBAgAABAgRyAgZQrnKBCRAgQIAAAQPIDxAgQIAAAQI5AQMoV7nABAgQIECAgAHkBwgQIECAAIGcgAGUq1xgAgQIECBAwADyAwQIECBAgEBOwADKVS4wAQIECBAgYAD5AQIECBAgQCAnYADlKheYAAECBAgQMID8AAECBAgQIJATMIBylQtMgAABAgQIGEB+gAABAgQIEMgJGEC5ygUmQIAAAQIEDCA/QIAAAQIECOQEDKBc5QITIECAAAECBpAfIECAAAECBHICBlCucoEJECBAgAABA8gPECBAgAABAjkBAyhXucAECBAgQICAAeQHCBAgQIAAgZyAAZSrXGACBAgQIEDAAPIDBAgQIECAQE7AAMpVLjABAgQIECBgAPkBAgQIECBAICdgAOUqF5gAAQIECBAwgPwAAQIECBAgkBMwgHKVC0yAAAECBAgYQH6AAAECBAgQyAkYQLnKBSZAgAABAgQMID9AgAABAgQI5AQMoFzlAhMgQIAAAQIGkB8gQIAAAQIEcgIGUK5ygQkQIECAAAEDyA8QIECAAAECOQEDKFe5wAQIECBAgIAB5AcIECBAgACBnIABlKtcYAIECBAgQMAA8gMECBAgQIBATsAAylUuMAECBAgQIGAA+QECBAgQIEAgJ2AA5SoXmAABAgQIEDCA/AABAgQIECCQEzCAcpULTIAAAQIECBhAfoAAAQIECBDICRhAucoFJkCAAAECBAwgP0CAAAECBAjkBAygXOUCEyBAgAABAgaQHyBAgAABAgRyAgZQrnKBCRAgQIAAAQPIDxAgQIAAAQI5AQMoV7nABAgQIECAgAHkBwgQIECAAIGcgAGUq1xgAgQIECBAwADyAwQIECBAgEBOwADKVS4wAQIECBAgYAD5AQIECBAgQCAnYADlKheYAAECBAgQMID8AAECBAgQIJATMIBylQtMgAABAgQIGEB+gAABAgQIEMgJGEC5ygUmQIAAAQIEDCA/QIAAAQIECOQEDKBc5QITIECAAAECBpAfIECAAAECBHICBlCucoEJECBAgACBB0MWAkEc/naKAAAAAElFTkSuQmCC\" width=\"576\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "(-0.5, 0.5)"
+      ]
+     },
+     "execution_count": 28,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "plt.figure(figsize=(8,8))\n",
+    "plt.plot(finalHoleX,finalHoleY,'b')\n",
+    "plt.xlim([-0.5,0.5])\n",
+    "plt.ylim([-0.5,0.5])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "np.savetxt('boundary_si_6arms.txt',np.transpose(np.array([finalHoleX,finalHoleY])))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Final Structure"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "[0, 60.0, 120.0, 180.0, 240.0, 300.0]\n"
+     ]
+    }
+   ],
+   "source": [
+    "holes = []\n",
+    "angle_increment = 360/6\n",
+    "hole_angles = [0]\n",
+    "while(hole_angles[-1]+angle_increment < 360.):\n",
+    "    hole_angles.append(hole_angles[-1]+angle_increment)\n",
+    "print(hole_angles)\n",
+    "for a in hole_angles:\n",
+    "    newX = []\n",
+    "    newY = []\n",
+    "    for i in range(len(finalHoleX)):\n",
+    "        p = rot([finalHoleX[i], finalHoleY[i]], a)\n",
+    "        newX.append(p[0])\n",
+    "        newY.append(p[1])\n",
+    "    holes.append([newX,newY])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Tightest spots of arms: 6.0124378098987625um\n",
+      "pmin: -0.3544019214225213, 0.31800081067889774\n",
+      "qmin: -0.35942287352644114, 0.32130829437319514\n"
+     ]
+    }
+   ],
+   "source": [
+    "#find tightest spot in arms\n",
+    "mindist = 1000.\n",
+    "pmin = [0.,0.]\n",
+    "qmin = [0.,0.]\n",
+    "for hi in range(-1,len(holes)-1):\n",
+    "    for i in range(len(holes[hi][0])):\n",
+    "        p = [holes[hi][0][i], holes[hi][1][i]]\n",
+    "        for j in range(len(holes[hi+1][0])):\n",
+    "            q = [holes[hi+1][0][j], holes[hi+1][1][j]]\n",
+    "            dist = np.sqrt((p[0]-q[0])**2 + (p[1]-q[1])**2)\n",
+    "            if(dist <= mindist):\n",
+    "                mindist = dist\n",
+    "                pmin = [p[0], p[1]]\n",
+    "                qmin = [q[0], q[1]]\n",
+    "print(f\"Tightest spots of arms: {mindist*1000.}um\")\n",
+    "print(f\"pmin: {pmin[0]}, {pmin[1]}\")\n",
+    "print(f\"qmin: {qmin[0]}, {qmin[1]}\")\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAtAAAALQCAYAAAC5V0ecAAAgAElEQVR4Xu3WoREAAAjEMNh/aVagPuhXOUR3HAECBAgQIECAAAECb4F9Lw0JECBAgAABAgQIEBgB7QkIECBAgAABAgQIBAEBHbBMCRAgQIAAAQIECAhoP0CAAAECBAgQIEAgCAjogGVKgAABAgQIECBAQED7AQIECBAgQIAAAQJBQEAHLFMCBAgQIECAAAECAtoPECBAgAABAgQIEAgCAjpgmRIgQIAAAQIECBAQ0H6AAAECBAgQIECAQBAQ0AHLlAABAgQIECBAgICA9gMECBAgQIAAAQIEgoCADlimBAgQIECAAAECBAS0HyBAgAABAgQIECAQBAR0wDIlQIAAAQIECBAgIKD9AAECBAgQIECAAIEgIKADlikBAgQIECBAgAABAe0HCBAgQIAAAQIECAQBAR2wTAkQIECAAAECBAgIaD9AgAABAgQIECBAIAgI6IBlSoAAAQIECBAgQEBA+wECBAgQIECAAAECQUBAByxTAgQIECBAgAABAgLaDxAgQIAAAQIECBAIAgI6YJkSIECAAAECBAgQENB+gAABAgQIECBAgEAQENABy5QAAQIECBAgQICAgPYDBAgQIECAAAECBIKAgA5YpgQIECBAgAABAgQEtB8gQIAAAQIECBAgEAQEdMAyJUCAAAECBAgQICCg/QABAgQIECBAgACBICCgA5YpAQIECBAgQIAAAQHtBwgQIECAAAECBAgEAQEdsEwJECBAgAABAgQICGg/QIAAAQIECBAgQCAICOiAZUqAAAECBAgQIEBAQPsBAgQIECBAgAABAkFAQAcsUwIECBAgQIAAAQIC2g8QIECAAAECBAgQCAICOmCZEiBAgAABAgQIEBDQfoAAAQIECBAgQIBAEBDQAcuUAAECBAgQIECAgID2AwQIECBAgAABAgSCgIAOWKYECBAgQIAAAQIEBLQfIECAAAECBAgQIBAEBHTAMiVAgAABAgQIECAgoP0AAQIECBAgQIAAgSAgoAOWKQECBAgQIECAAAEB7QcIECBAgAABAgQIBAEBHbBMCRAgQIAAAQIECAhoP0CAAAECBAgQIEAgCAjogGVKgAABAgQIECBAQED7AQIECBAgQIAAAQJBQEAHLFMCBAgQIECAAAECAtoPECBAgAABAgQIEAgCAjpgmRIgQIAAAQIECBAQ0H6AAAECBAgQIECAQBAQ0AHLlAABAgQIECBAgICA9gMECBAgQIAAAQIEgoCADlimBAgQIECAAAECBAS0HyBAgAABAgQIECAQBAR0wDIlQIAAAQIECBAgIKD9AAECBAgQIECAAIEgIKADlikBAgQIECBAgAABAe0HCBAgQIAAAQIECAQBAR2wTAkQIECAAAECBAgIaD9AgAABAgQIECBAIAgI6IBlSoAAAQIECBAgQEBA+wECBAgQIECAAAECQUBAByxTAgQIECBAgAABAgLaDxAgQIAAAQIECBAIAgI6YJkSIECAAAECBAgQENB+gAABAgQIECBAgEAQENABy5QAAQIECBAgQICAgPYDBAgQIECAAAECBIKAgA5YpgQIECBAgAABAgQEtB8gQIAAAQIECBAgEAQEdMAyJUCAAAECBAgQICCg/QABAgQIECBAgACBICCgA5YpAQIECBAgQIAAAQHtBwgQIECAAAECBAgEAQEdsEwJECBAgAABAgQICGg/QIAAAQIECBAgQCAICOiAZUqAAAECBAgQIEBAQPsBAgQIECBAgAABAkFAQAcsUwIECBAgQIAAAQIC2g8QIECAAAECBAgQCAICOmCZEiBAgAABAgQIEBDQfoAAAQIECBAgQIBAEBDQAcuUAAECBAgQIECAgID2AwQIECBAgAABAgSCgIAOWKYECBAgQIAAAQIEBLQfIECAAAECBAgQIBAEBHTAMiVAgAABAgQIECAgoP0AAQIECBAgQIAAgSAgoAOWKQECBAgQIECAAAEB7QcIECBAgAABAgQIBAEBHbBMCRAgQIAAAQIECAhoP0CAAAECBAgQIEAgCAjogGVKgAABAgQIECBAQED7AQIECBAgQIAAAQJBQEAHLFMCBAgQIECAAAECAtoPECBAgAABAgQIEAgCAjpgmRIgQIAAAQIECBAQ0H6AAAECBAgQIECAQBAQ0AHLlAABAgQIECBAgICA9gMECBAgQIAAAQIEgoCADlimBAgQIECAAAECBAS0HyBAgAABAgQIECAQBAR0wDIlQIAAAQIECBAgIKD9AAECBAgQIECAAIEgIKADlikBAgQIECBAgAABAe0HCBAgQIAAAQIECAQBAR2wTAkQIECAAAECBAgIaD9AgAABAgQIECBAIAgI6IBlSoAAAQIECBAgQEBA+wECBAgQIECAAAECQUBAByxTAgQIECBAgAABAgLaDxAgQIAAAQIECBAIAgI6YJkSIECAAAECBAgQENB+gAABAgQIECBAgEAQENABy5QAAQIECBAgQICAgPYDBAgQIECAAAECBIKAgA5YpgQIECBAgAABAgQEtB8gQIAAAQIECBAgEAQEdMAyJUCAAAECBAgQICCg/QABAgQIECBAgACBICCgA5YpAQIECBAgQIAAAQHtBwgQIECAAAECBAgEAQEdsEwJECBAgAABAgQICGg/QIAAAQIECBAgQCAICOiAZUqAAAECBAgQIEBAQPsBAgQIECBAgAABAkFAQAcsUwIECBAgQIAAAQIC2g8QIECAAAECBAgQCAICOmCZEiBAgAABAgQIEBDQfoAAAQIECBAgQIBAEBDQAcuUAAECBAgQIECAgID2AwQIECBAgAABAgSCgIAOWKYECBAgQIAAAQIEBLQfIECAAAECBAgQIBAEBHTAMiVAgAABAgQIECAgoP0AAQIECBAgQIAAgSAgoAOWKQECBAgQIECAAAEB7QcIECBAgAABAgQIBAEBHbBMCRAgQIAAAQIECAhoP0CAAAECBAgQIEAgCAjogGVKgAABAgQIECBAQED7AQIECBAgQIAAAQJBQEAHLFMCBAgQIECAAAECAtoPECBAgAABAgQIEAgCAjpgmRIgQIAAAQIECBAQ0H6AAAECBAgQIECAQBAQ0AHLlAABAgQIECBAgICA9gMECBAgQIAAAQIEgoCADlimBAgQIECAAAECBAS0HyBAgAABAgQIECAQBAR0wDIlQIAAAQIECBAgIKD9AAECBAgQIECAAIEgIKADlikBAgQIECBAgAABAe0HCBAgQIAAAQIECAQBAR2wTAkQIECAAAECBAgIaD9AgAABAgQIECBAIAgI6IBlSoAAAQIECBAgQEBA+wECBAgQIECAAAECQUBAByxTAgQIECBAgAABAgLaDxAgQIAAAQIECBAIAgI6YJkSIECAAAECBAgQENB+gAABAgQIECBAgEAQENABy5QAAQIECBAgQICAgPYDBAgQIECAAAECBIKAgA5YpgQIECBAgAABAgQEtB8gQIAAAQIECBAgEAQEdMAyJUCAAAECBAgQICCg/QABAgQIECBAgACBICCgA5YpAQIECBAgQIAAAQHtBwgQIECAAAECBAgEAQEdsEwJECBAgAABAgQICGg/QIAAAQIECBAgQCAICOiAZUqAAAECBAgQIEBAQPsBAgQIECBAgAABAkFAQAcsUwIECBAgQIAAAQIC2g8QIECAAAECBAgQCAICOmCZEiBAgAABAgQIEBDQfoAAAQIECBAgQIBAEBDQAcuUAAECBAgQIECAgID2AwQIECBAgAABAgSCgIAOWKYECBAgQIAAAQIEBLQfIECAAAECBAgQIBAEBHTAMiVAgAABAgQIECAgoP0AAQIECBAgQIAAgSAgoAOWKQECBAgQIECAAAEB7QcIECBAgAABAgQIBAEBHbBMCRAgQIAAAQIECAhoP0CAAAECBAgQIEAgCAjogGVKgAABAgQIECBAQED7AQIECBAgQIAAAQJBQEAHLFMCBAgQIECAAAECAtoPECBAgAABAgQIEAgCAjpgmRIgQIAAAQIECBAQ0H6AAAECBAgQIECAQBAQ0AHLlAABAgQIECBAgICA9gMECBAgQIAAAQIEgoCADlimBAgQIECAAAECBAS0HyBAgAABAgQIECAQBAR0wDIlQIAAAQIECBAgIKD9AAECBAgQIECAAIEgIKADlikBAgQIECBAgAABAe0HCBAgQIAAAQIECAQBAR2wTAkQIECAAAECBAgIaD9AgAABAgQIECBAIAgI6IBlSoAAAQIECBAgQEBA+wECBAgQIECAAAECQUBAByxTAgQIECBAgAABAgLaDxAgQIAAAQIECBAIAgI6YJkSIECAAAECBAgQENB+gAABAgQIECBAgEAQENABy5QAAQIECBAgQICAgPYDBAgQIECAAAECBIKAgA5YpgQIECBAgAABAgQEtB8gQIAAAQIECBAgEAQEdMAyJUCAAAECBAgQICCg/QABAgQIECBAgACBICCgA5YpAQIECBAgQIAAAQHtBwgQIECAAAECBAgEAQEdsEwJECBAgAABAgQICGg/QIAAAQIECBAgQCAICOiAZUqAAAECBAgQIEBAQPsBAgQIECBAgAABAkFAQAcsUwIECBAgQIAAAQIC2g8QIECAAAECBAgQCAICOmCZEiBAgAABAgQIEBDQfoAAAQIECBAgQIBAEBDQAcuUAAECBAgQIECAgID2AwQIECBAgAABAgSCgIAOWKYECBAgQIAAAQIEBLQfIECAAAECBAgQIBAEBHTAMiVAgAABAgQIECAgoP0AAQIECBAgQIAAgSAgoAOWKQECBAgQIECAAAEB7QcIECBAgAABAgQIBAEBHbBMCRAgQIAAAQIECAhoP0CAAAECBAgQIEAgCAjogGVKgAABAgQIECBAQED7AQIECBAgQIAAAQJBQEAHLFMCBAgQIECAAAECAtoPECBAgAABAgQIEAgCAjpgmRIgQIAAAQIECBAQ0H6AAAECBAgQIECAQBAQ0AHLlAABAgQIECBAgICA9gMECBAgQIAAAQIEgoCADlimBAgQIECAAAECBAS0HyBAgAABAgQIECAQBAR0wDIlQIAAAQIECBAgIKD9AAECBAgQIECAAIEgIKADlikBAgQIECBAgAABAe0HCBAgQIAAAQIECAQBAR2wTAkQIECAAAECBAgIaD9AgAABAgQIECBAIAgI6IBlSoAAAQIECBAgQEBA+wECBAgQIECAAAECQUBAByxTAgQIECBAgAABAgLaDxAgQIAAAQIECBAIAgI6YJkSIECAAAECBAgQENB+gAABAgQIECBAgEAQENABy5QAAQIECBAgQICAgPYDBAgQIECAAAECBIKAgA5YpgQIECBAgAABAgQEtB8gQIAAAQIECBAgEAQEdMAyJUCAAAECBAgQICCg/QABAgQIECBAgACBICCgA5YpAQIECBAgQIAAAQHtBwgQIECAAAECBAgEAQEdsEwJECBAgAABAgQICGg/QIAAAQIECBAgQCAICOiAZUqAAAECBAgQIEBAQPsBAgQIECBAgAABAkFAQAcsUwIECBAgQIAAAQIC2g8QIECAAAECBAgQCAICOmCZEiBAgAABAgQIEBDQfoAAAQIECBAgQIBAEBDQAcuUAAECBAgQIECAgID2AwQIECBAgAABAgSCgIAOWKYECBAgQIAAAQIEBLQfIECAAAECBAgQIBAEBHTAMiVAgAABAgQIECAgoP0AAQIECBAgQIAAgSAgoAOWKQECBAgQIECAAAEB7QcIECBAgAABAgQIBAEBHbBMCRAgQIAAAQIECAhoP0CAAAECBAgQIEAgCAjogGVKgAABAgQIECBAQED7AQIECBAgQIAAAQJBQEAHLFMCBAgQIECAAAECAtoPECBAgAABAgQIEAgCAjpgmRIgQIAAAQIECBAQ0H6AAAECBAgQIECAQBAQ0AHLlAABAgQIECBAgICA9gMECBAgQIAAAQIEgoCADlimBAgQIECAAAECBAS0HyBAgAABAgQIECAQBAR0wDIlQIAAAQIECBAgIKD9AAECBAgQIECAAIEgIKADlikBAgQIECBAgAABAe0HCBAgQIAAAQIECAQBAR2wTAkQIECAAAECBAgIaD9AgAABAgQIECBAIAgI6IBlSoAAAQIECBAgQEBA+wECBAgQIECAAAECQUBAByxTAgQIECBAgAABAgLaDxAgQIAAAQIECBAIAgI6YJkSIECAAAECBAgQENB+gAABAgQIECBAgEAQENABy5QAAQIECBAgQICAgPYDBAgQIECAAAECBIKAgA5YpgQIECBAgAABAgQEtB8gQIAAAQIECBAgEAQEdMAyJUCAAAECBAgQICCg/QABAgQIECBAgACBICCgA5YpAQIECBAgQIAAAQHtBwgQIECAAAECBAgEAQEdsEwJECBAgAABAgQICGg/QIAAAQIECBAgQCAICOiAZUqAAAECBAgQIEBAQPsBAgQIECBAgAABAkFAQAcsUwIECBAgQIAAAQIC2g8QIECAAAECBAgQCAICOmCZEiBAgAABAgQIEBDQfoAAAQIECBAgQIBAEBDQAcuUAAECBAgQIECAgID2AwQIECBAgAABAgSCgIAOWKYECBAgQIAAAQIEBLQfIECAAAECBAgQIBAEBHTAMiVAgAABAgQIECAgoP0AAQIECBAgQIAAgSAgoAOWKQECBAgQIECAAAEB7QcIECBAgAABAgQIBAEBHbBMCRAgQIAAAQIECAhoP0CAAAECBAgQIEAgCAjogGVKgAABAgQIECBAQED7AQIECBAgQIAAAQJBQEAHLFMCBAgQIECAAAECAtoPECBAgAABAgQIEAgCAjpgmRIgQIAAAQIECBAQ0H6AAAECBAgQIECAQBAQ0AHLlAABAgQIECBAgICA9gMECBAgQIAAAQIEgoCADlimBAgQIECAAAECBAS0HyBAgAABAgQIECAQBAR0wDIlQIAAAQIECBAgIKD9AAECBAgQIECAAIEgIKADlikBAgQIECBAgAABAe0HCBAgQIAAAQIECAQBAR2wTAkQIECAAAECBAgIaD9AgAABAgQIECBAIAgI6IBlSoAAAQIECBAgQEBA+wECBAgQIECAAAECQUBAByxTAgQIECBAgAABAgLaDxAgQIAAAQIECBAIAgI6YJkSIECAAAECBAgQENB+gAABAgQIECBAgEAQENABy5QAAQIECBAgQICAgPYDBAgQIECAAAECBIKAgA5YpgQIECBAgAABAgQEtB8gQIAAAQIECBAgEAQEdMAyJUCAAAECBAgQICCg/QABAgQIECBAgACBICCgA5YpAQIECBAgQIAAAQHtBwgQIECAAAECBAgEAQEdsEwJECBAgAABAgQICGg/QIAAAQIECBAgQCAICOiAZUqAAAECBAgQIEBAQPsBAgQIECBAgAABAkFAQAcsUwIECBAgQIAAAQIC2g8QIECAAAECBAgQCAICOmCZEiBAgAABAgQIEBDQfoAAAQIECBAgQIBAEBDQAcuUAAECBAgQIECAgID2AwQIECBAgAABAgSCgIAOWKYECBAgQIAAAQIEBLQfIECAAAECBAgQIBAEBHTAMiVAgAABAgQIECAgoP0AAQIECBAgQIAAgSAgoAOWKQECBAgQIECAAAEB7QcIECBAgAABAgQIBAEBHbBMCRAgQIAAAQIECAhoP0CAAAECBAgQIEAgCAjogGVKgAABAgQIECBAQED7AQIECBAgQIAAAQJBQEAHLFMCBAgQIECAAAECAtoPECBAgAABAgQIEAgCAjpgmRIgQIAAAQIECBAQ0H6AAAECBAgQIECAQBAQ0AHLlAABAgQIECBAgICA9gMECBAgQIAAAQIEgoCADlimBAgQIECAAAECBAS0HyBAgAABAgQIECAQBAR0wDIlQIAAAQIECBAgIKD9AAECBAgQIECAAIEgIKADlikBAgQIECBAgAABAe0HCBAgQIAAAQIECAQBAR2wTAkQIECAAAECBAgIaD9AgAABAgQIECBAIAgI6IBlSoAAAQIECBAgQEBA+wECBAgQIECAAAECQUBAByxTAgQIECBAgAABAgLaDxAgQIAAAQIECBAIAgI6YJkSIECAAAECBAgQENB+gAABAgQIECBAgEAQENABy5QAAQIECBAgQICAgPYDBAgQIECAAAECBIKAgA5YpgQIECBAgAABAgQEtB8gQIAAAQIECBAgEAQEdMAyJUCAAAECBAgQICCg/QABAgQIECBAgACBICCgA5YpAQIECBAgQIAAAQHtBwgQIECAAAECBAgEAQEdsEwJECBAgAABAgQICGg/QIAAAQIECBAgQCAICOiAZUqAAAECBAgQIEBAQPsBAgQIECBAgAABAkFAQAcsUwIECBAgQIAAAQIC2g8QIECAAAECBAgQCAICOmCZEiBAgAABAgQIEBDQfoAAAQIECBAgQIBAEBDQAcuUAAECBAgQIECAgID2AwQIECBAgAABAgSCgIAOWKYECBAgQIAAAQIEBLQfIECAAAECBAgQIBAEBHTAMiVAgAABAgQIECAgoP0AAQIECBAgQIAAgSAgoAOWKQECBAgQIECAAAEB7QcIECBAgAABAgQIBAEBHbBMCRAgQIAAAQIECAhoP0CAAAECBAgQIEAgCAjogGVKgAABAgQIECBAQED7AQIECBAgQIAAAQJBQEAHLFMCBAgQIECAAAECAtoPECBAgAABAgQIEAgCAjpgmRIgQIAAAQIECBAQ0H6AAAECBAgQIECAQBAQ0AHLlAABAgQIECBAgICA9gMECBAgQIAAAQIEgoCADlimBAgQIECAAAECBAS0HyBAgAABAgQIECAQBAR0wDIlQIAAAQIECBAgIKD9AAECBAgQIECAAIEgIKADlikBAgQIECBAgAABAe0HCBAgQIAAAQIECAQBAR2wTAkQIECAAAECBAgIaD9AgAABAgQIECBAIAgI6IBlSoAAAQIECBAgQEBA+wECBAgQIECAAAECQUBAByxTAgQIECBAgAABAgLaDxAgQIAAAQIECBAIAgI6YJkSIECAAAECBAgQENB+gAABAgQIECBAgEAQENABy5QAAQIECBAgQICAgPYDBAgQIECAAAECBIKAgA5YpgQIECBAgAABAgQEtB8gQIAAAQIECBAgEAQEdMAyJUCAAAECBAgQICCg/QABAgQIECBAgACBICCgA5YpAQIECBAgQIAAAQHtBwgQIECAAAECBAgEAQEdsEwJECBAgAABAgQICGg/QIAAAQIECBAgQCAICOiAZUqAAAECBAgQIEBAQPsBAgQIECBAgAABAkFAQAcsUwIECBAgQIAAAQIC2g8QIECAAAECBAgQCAICOmCZEiBAgAABAgQIEBDQfoAAAQIECBAgQIBAEBDQAcuUAAECBAgQIECAgID2AwQIECBAgAABAgSCgIAOWKYECBAgQIAAAQIEBLQfIECAAAECBAgQIBAEBHTAMiVAgAABAgQIECAgoP0AAQIECBAgQIAAgSAgoAOWKQECBAgQIECAAAEB7QcIECBAgAABAgQIBAEBHbBMCRAgQIAAAQIECAhoP0CAAAECBAgQIEAgCAjogGVKgAABAgQIECBAQED7AQIECBAgQIAAAQJBQEAHLFMCBAgQIECAAAECAtoPECBAgAABAgQIEAgCAjpgmRIgQIAAAQIECBAQ0H6AAAECBAgQIECAQBAQ0AHLlAABAgQIECBAgICA9gMECBAgQIAAAQIEgoCADlimBAgQIECAAAECBAS0HyBAgAABAgQIECAQBAR0wDIlQIAAAQIECBAgIKD9AAECBAgQIECAAIEgIKADlikBAgQIECBAgAABAe0HCBAgQIAAAQIECAQBAR2wTAkQIECAAAECBAgIaD9AgAABAgQIECBAIAgI6IBlSoAAAQIECBAgQEBA+wECBAgQIECAAAECQUBAByxTAgQIECBAgAABAgLaDxAgQIAAAQIECBAIAgI6YJkSIECAAAECBAgQENB+gAABAgQIECBAgEAQENABy5QAAQIECBAgQICAgPYDBAgQIECAAAECBIKAgA5YpgQIECBAgAABAgQEtB8gQIAAAQIECBAgEAQEdMAyJUCAAAECBAgQICCg/QABAgQIECBAgACBICCgA5YpAQIECBAgQIAAAQHtBwgQIECAAAECBAgEAQEdsEwJECBAgAABAgQICGg/QIAAAQIECBAgQCAICOiAZUqAAAECBAgQIEBAQPsBAgQIECBAgAABAkFAQAcsUwIECBAgQIAAAQIC2g8QIECAAAECBAgQCAICOmCZEiBAgAABAgQIEBDQfoAAAQIECBAgQIBAEBDQAcuUAAECBAgQIECAgID2AwQIECBAgAABAgSCgIAOWKYECBAgQIAAAQIEBLQfIECAAAECBAgQIBAEBHTAMiVAgAABAgQIECAgoP0AAQIECBAgQIAAgSAgoAOWKQECBAgQIECAAAEB7QcIECBAgAABAgQIBAEBHbBMCRAgQIAAAQIECAhoP0CAAAECBAgQIEAgCAjogGVKgAABAgQIECBAQED7AQIECBAgQIAAAQJBQEAHLFMCBAgQIECAAAECAtoPECBAgAABAgQIEAgCAjpgmRIgQIAAAQIECBAQ0H6AAAECBAgQIECAQBAQ0AHLlAABAgQIECBAgICA9gMECBAgQIAAAQIEgoCADlimBAgQIECAAAECBAS0HyBAgAABAgQIECAQBAR0wDIlQIAAAQIECBAgIKD9AAECBAgQIECAAIEgIKADlikBAgQIECBAgAABAe0HCBAgQIAAAQIECAQBAR2wTAkQIECAAAECBAgIaD9AgAABAgQIECBAIAgI6IBlSoAAAQIECBAgQEBA+wECBAgQIECAAAECQUBAByxTAgQIECBAgAABAgLaDxAgQIAAAQIECBAIAgI6YJkSIECAAAECBAgQENB+gAABAgQIECBAgEAQENABy5QAAQIECBAgQICAgPYDBFVXY5AAAAlpSURBVAgQIECAAAECBIKAgA5YpgQIECBAgAABAgQEtB8gQIAAAQIECBAgEAQEdMAyJUCAAAECBAgQICCg/QABAgQIECBAgACBICCgA5YpAQIECBAgQIAAAQHtBwgQIECAAAECBAgEAQEdsEwJECBAgAABAgQICGg/QIAAAQIECBAgQCAICOiAZUqAAAECBAgQIEBAQPsBAgQIECBAgAABAkFAQAcsUwIECBAgQIAAAQIC2g8QIECAAAECBAgQCAICOmCZEiBAgAABAgQIEBDQfoAAAQIECBAgQIBAEBDQAcuUAAECBAgQIECAgID2AwQIECBAgAABAgSCgIAOWKYECBAgQIAAAQIEBLQfIECAAAECBAgQIBAEBHTAMiVAgAABAgQIECAgoP0AAQIECBAgQIAAgSAgoAOWKQECBAgQIECAAAEB7QcIECBAgAABAgQIBAEBHbBMCRAgQIAAAQIECAhoP0CAAAECBAgQIEAgCAjogGVKgAABAgQIECBAQED7AQIECBAgQIAAAQJBQEAHLFMCBAgQIECAAAECAtoPECBAgAABAgQIEAgCAjpgmRIgQIAAAQIECBAQ0H6AAAECBAgQIECAQBAQ0AHLlAABAgQIECBAgICA9gMECBAgQIAAAQIEgoCADlimBAgQIECAAAECBAS0HyBAgAABAgQIECAQBAR0wDIlQIAAAQIECBAgIKD9AAECBAgQIECAAIEgIKADlikBAgQIECBAgAABAe0HCBAgQIAAAQIECAQBAR2wTAkQIECAAAECBAgIaD9AgAABAgQIECBAIAgI6IBlSoAAAQIECBAgQEBA+wECBAgQIECAAAECQUBAByxTAgQIECBAgAABAgLaDxAgQIAAAQIECBAIAgI6YJkSIECAAAECBAgQENB+gAABAgQIECBAgEAQENABy5QAAQIECBAgQICAgPYDBAgQIECAAAECBIKAgA5YpgQIECBAgAABAgQEtB8gQIAAAQIECBAgEAQEdMAyJUCAAAECBAgQICCg/QABAgQIECBAgACBICCgA5YpAQIECBAgQIAAAQHtBwgQIECAAAECBAgEAQEdsEwJECBAgAABAgQICGg/QIAAAQIECBAgQCAICOiAZUqAAAECBAgQIEBAQPsBAgQIECBAgAABAkFAQAcsUwIECBAgQIAAAQIC2g8QIECAAAECBAgQCAICOmCZEiBAgAABAgQIEBDQfoAAAQIECBAgQIBAEBDQAcuUAAECBAgQIECAgID2AwQIECBAgAABAgSCgIAOWKYECBAgQIAAAQIEBLQfIECAAAECBAgQIBAEBHTAMiVAgAABAgQIECAgoP0AAQIECBAgQIAAgSAgoAOWKQECBAgQIECAAAEB7QcIECBAgAABAgQIBAEBHbBMCRAgQIAAAQIECAhoP0CAAAECBAgQIEAgCAjogGVKgAABAgQIECBAQED7AQIECBAgQIAAAQJBQEAHLFMCBAgQIECAAAECAtoPECBAgAABAgQIEAgCAjpgmRIgQIAAAQIECBAQ0H6AAAECBAgQIECAQBAQ0AHLlAABAgQIECBAgICA9gMECBAgQIAAAQIEgoCADlimBAgQIECAAAECBAS0HyBAgAABAgQIECAQBAR0wDIlQIAAAQIECBAgIKD9AAECBAgQIECAAIEgIKADlikBAgQIECBAgAABAe0HCBAgQIAAAQIECAQBAR2wTAkQIECAAAECBAgIaD9AgAABAgQIECBAIAgI6IBlSoAAAQIECBAgQEBA+wECBAgQIECAAAECQUBAByxTAgQIECBAgAABAgLaDxAgQIAAAQIECBAIAgI6YJkSIECAAAECBAgQENB+gAABAgQIECBAgEAQENABy5QAAQIECBAgQICAgPYDBAgQIECAAAECBIKAgA5YpgQIECBAgAABAgQEtB8gQIAAAQIECBAgEAQEdMAyJUCAAAECBAgQICCg/QABAgQIECBAgACBICCgA5YpAQIECBAgQIAAAQHtBwgQIECAAAECBAgEAQEdsEwJECBAgAABAgQICGg/QIAAAQIECBAgQCAICOiAZUqAAAECBAgQIEBAQPsBAgQIECBAgAABAkFAQAcsUwIECBAgQIAAAQIC2g8QIECAAAECBAgQCAICOmCZEiBAgAABAgQIEBDQfoAAAQIECBAgQIBAEBDQAcuUAAECBAgQIECAgID2AwQIECBAgAABAgSCgIAOWKYECBAgQIAAAQIEBLQfIECAAAECBAgQIBAEBHTAMiVAgAABAgQIECAgoP0AAQIECBAgQIAAgSAgoAOWKQECBAgQIECAAAEB7QcIECBAgAABAgQIBAEBHbBMCRAgQIAAAQIECAhoP0CAAAECBAgQIEAgCAjogGVKgAABAgQIECBAQED7AQIECBAgQIAAAQJBQEAHLFMCBAgQIECAAAECAtoPECBAgAABAgQIEAgCAjpgmRIgQIAAAQIECBAQ0H6AAAECBAgQIECAQBAQ0AHLlAABAgQIECBAgICA9gMECBAgQIAAAQIEgoCADlimBAgQIECAAAECBAS0HyBAgAABAgQIECAQBAR0wDIlQIAAAQIECBAgIKD9AAECBAgQIECAAIEgIKADlikBAgQIECBAgAABAe0HCBAgQIAAAQIECAQBAR2wTAkQIECAAAECBAgIaD9AgAABAgQIECBAIAgI6IBlSoAAAQIECBAgQEBA+wECBAgQIECAAAECQUBAByxTAgQIECBAgAABAgLaDxAgQIAAAQIECBAIAgI6YJkSIECAAAECBAgQENB+gAABAgQIECBAgEAQENABy5QAAQIECBAgQICAgPYDBAgQIECAAAECBIKAgA5YpgQIECBAgAABAgQEtB8gQIAAAQIECBAgEAQEdMAyJUCAAAECBAgQICCg/QABAgQIECBAgACBICCgA5YpAQIECBAgQIAAAQHtBwgQIECAAAECBAgEAQEdsEwJECBAgAABAgQICGg/QIAAAQIECBAgQCAICOiAZUqAAAECBAgQIEBAQPsBAgQIECBAgAABAkFAQAcsUwIECBAgQIAAAQIC2g8QIECAAAECBAgQCAICOmCZEiBAgAABAgQIEBDQfoAAAQIECBAgQIBAEBDQAcuUAAECBAgQIECAgID2AwQIECBAgAABAgSCgIAOWKYECBAgQIAAAQIEBLQfIECAAAECBAgQIBAEBHTAMiVAgAABAgQIECBwrUQC0ZYJhPQAAAAASUVORK5CYII=\" width=\"720\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5ea279610>]"
+      ]
+     },
+     "execution_count": 32,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "%matplotlib notebook\n",
+    "plt.figure(figsize=(10,10))\n",
+    "for h in holes:\n",
+    "    plt.plot(h[0], h[1], 'b')\n",
+    "plt.plot([pmin[0]],pmin[1],'*',c='r')\n",
+    "plt.plot([qmin[0]],qmin[1],'*',c='r')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Generate SpaceClaim File"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def SC_curves(holes, filename):\n",
+    "    printstring = '3d = true\\npolyline = true\\nfit = false\\nfittol = 0.0001\\n\\n'\n",
+    "    for hi, h in enumerate(holes):\n",
+    "        for i in range(len(h[0])):\n",
+    "            printstring += f'{h[0][i]} {h[1][i]} 0\\n'\n",
+    "        printstring += '\\n'\n",
+    "    with open(filename, 'w') as file:\n",
+    "        file.write(printstring)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "SC_curves(holes, 'polylines_0.txt')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Generate Current Silicon Nitride Design for SpaceClaim"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "num_holes = 36\n",
+    "holes = []\n",
+    "angle = 0.\n",
+    "dangle = 360. / num_holes\n",
+    "while angle < 359.99:\n",
+    "    newXs = []\n",
+    "    newYs = []\n",
+    "    for i in range(len(filterX)):\n",
+    "        p = rot([filterX[i], filterY[i]], angle)\n",
+    "        newXs.append(p[0])\n",
+    "        newYs.append(p[1])\n",
+    "    holes.append([newXs, newYs])\n",
+    "    angle += dangle"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "SC_curves(holes, 'polylines_1.txt')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Plot the holes"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "pxs = []\n",
+    "pys = []\n",
+    "for h in holes:\n",
+    "    pxs.append([])\n",
+    "    pys.append([])\n",
+    "    for i in range(len(h[0])):\n",
+    "        pxs[-1].append(h[0][i])\n",
+    "        pys[-1].append(h[1][i])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "%matplotlib notebook\n",
+    "#for i in range(len(pxs)):\n",
+    "#    plt.plot(pxs[i],pys[i])\n",
+    "plt.plot(pxs[0],pys[0])\n",
+    "plt.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Check the dimensions"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Combo 0,1: Arm Width 4.7227758290841555 um\n",
+      "Combo 1,2: Arm Width 4.722775829084213 um\n",
+      "Combo 2,3: Arm Width 4.7227758290841395 um\n",
+      "Combo 3,4: Arm Width 4.722775829084109 um\n",
+      "Combo 4,5: Arm Width 4.72277582908416 um\n",
+      "Combo 5,6: Arm Width 4.722775829084169 um\n",
+      "Combo 6,7: Arm Width 4.722775829084106 um\n",
+      "Combo 7,8: Arm Width 4.722775829084162 um\n",
+      "Combo 8,9: Arm Width 4.7227758290841635 um\n",
+      "Combo 9,10: Arm Width 4.722775829084099 um\n",
+      "Combo 10,11: Arm Width 4.722775829084212 um\n",
+      "Combo 11,12: Arm Width 4.72277582908413 um\n",
+      "Combo 12,13: Arm Width 4.722775829084148 um\n",
+      "Combo 13,14: Arm Width 4.722775829084185 um\n",
+      "Combo 14,15: Arm Width 4.722775829084179 um\n",
+      "Combo 15,16: Arm Width 4.722775829084103 um\n",
+      "Combo 16,17: Arm Width 4.722775829084116 um\n",
+      "Combo 17,18: Arm Width 4.722775829084196 um\n",
+      "Combo 18,19: Arm Width 4.72277582908413 um\n",
+      "Combo 19,20: Arm Width 4.7227758290841635 um\n",
+      "Combo 20,21: Arm Width 4.722775829084152 um\n",
+      "Combo 21,22: Arm Width 4.722775829084139 um\n",
+      "Combo 22,23: Arm Width 4.72277582908421 um\n",
+      "Combo 23,24: Arm Width 4.72277582908418 um\n",
+      "Combo 24,25: Arm Width 4.722775829084141 um\n",
+      "Combo 25,26: Arm Width 4.722775829084071 um\n",
+      "Combo 26,27: Arm Width 4.722775829084156 um\n",
+      "Combo 27,28: Arm Width 4.722775829084128 um\n",
+      "Combo 28,29: Arm Width 4.722775829084108 um\n",
+      "Combo 29,30: Arm Width 4.722775829084183 um\n",
+      "Combo 30,31: Arm Width 4.722775829084184 um\n",
+      "Combo 31,32: Arm Width 4.722775829084098 um\n",
+      "Combo 32,33: Arm Width 4.722775829084091 um\n",
+      "Combo 33,34: Arm Width 4.722775829084154 um\n",
+      "Combo 34,35: Arm Width 4.722775829084145 um\n",
+      "Combo 35,0: Arm Width 4.722775829084151 um\n"
+     ]
+    }
+   ],
+   "source": [
+    "#find minimum arm size\n",
+    "for i in range(len(holes)):\n",
+    "    mindist = 10000.\n",
+    "    h0 = holes[i]\n",
+    "    h1 = holes[(i+1)%(len(holes))]\n",
+    "    x0s = h0[0]\n",
+    "    y0s = h0[1]\n",
+    "    x1s = h1[0]\n",
+    "    y1s = h1[1]\n",
+    "    for j in range(len(x0s)):\n",
+    "        for k in range(len(x1s)):\n",
+    "            p0 = [x0s[j], y0s[j]]\n",
+    "            p1 = [x1s[k], y1s[k]]\n",
+    "            dist = np.sqrt((p0[0]-p1[0])**2 + (p0[1]-p1[1])**2)\n",
+    "            if dist < mindist:\n",
+    "                mindist = dist\n",
+    "    print(f\"Combo {i},{(i+1)%len(holes)}: Arm Width {mindist*1000.} um\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Smoothen Corners"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def intersect_straights(p, r, q, r_pr):\n",
+    "    if(math.isclose(r[0], 0.) and math.isclose(r[1], 0.)):\n",
+    "        print(\"INTERSECT_ERROR: Straight 0 has degenerate direction vector.\")\n",
+    "        return None\n",
+    "    if(math.isclose(r_pr[0], 0.) and math.isclose(r_pr[1], 0.)):\n",
+    "        print(\"INTERSECT_ERROR: Straight 1 has degenerate direction vector.\")\n",
+    "        return None\n",
+    "    if math.isclose(r[0] / r[1], r_pr[0] / r_pr[1]):\n",
+    "        print(\"INTERSECT_ERROR: Straights are parallel.\")\n",
+    "        return None\n",
+    "    if math.isclose(r[1], 0.):\n",
+    "        print(\"INTERSECT_ERROR: Method needs extension, ry=0 encountered.\")\n",
+    "        return None\n",
+    "    #calculate intersection parameters\n",
+    "    s = (p[0] - q[0] + r[0] / r[1] * (q[1] - p[1])) / (r_pr[0] - r[0] * r_pr[1] / r[1])\n",
+    "    t = (q[1] - p[1] + s * r_pr[1]) / r[1]\n",
+    "    #calculate the arising intersection points\n",
+    "    int_s = [q[0] + s * r_pr[0], q[1] + s * r_pr[1]]\n",
+    "    int_t = [p[0] + t * r[0], p[1] + t * r[1]]\n",
+    "    if not ( math.isclose(int_s[0], int_t[0]) ) and ( math.isclose(int_s[1], int_t[1]) ):\n",
+    "            print(f\"INTERSECT_ERROR: Calculated intersections do not agree in x (delta {int_t[0] - int_s[0]:.6f}): {int_t[0]:.6f} vs {int_s[0]:.6f}\")\n",
+    "            return None\n",
+    "    elif not ( math.isclose(int_s[1], int_t[1]) ) and ( math.isclose(int_s[0], int_t[0]) ):\n",
+    "            print(f\"INTERSECT_ERROR: Calculated intersections do not agree in y (delta {int_t[1] - int_s[1]:.6f}): {int_t[1]:.6f} vs {int_s[1]:.6f}\")\n",
+    "            return None\n",
+    "    elif not ( math.isclose(int_s[0], int_t[0]) and math.isclose(int_s[1], int_t[1]) ):\n",
+    "        print(f\"INTERSECT_ERROR: Calculated intersections do not agree (int_t = [{int_t[0]:.6f}, {int_t[1]:.6f}], int_s = [{int_s[0]:.6f}, {int_s[1]:.6f}])\")\n",
+    "        return None\n",
+    "    return int_s\n",
+    "\n",
+    "def intersect_segments(seg0_p0, seg0_p1, seg2_p0, seg2_p1):\n",
+    "    r = [seg0_p1[0]-seg0_p0[0], seg0_p1[1]-seg0_p0[1]]\n",
+    "    r_pr = [seg2_p0[0]-seg2_p1[0], seg2_p0[1]-seg2_p1[1]]\n",
+    "    p = [seg0_p0[0], seg0_p0[1]]\n",
+    "    q = [seg2_p1[0], seg2_p1[1]]\n",
+    "    \n",
+    "    return intersect_straights(p, r, q, r_pr)\n",
+    "\n",
+    "def point_at_half_distance(seg1_p0, seg1_p1, intersection):\n",
+    "    #straight along segment\n",
+    "    r = [seg1_p1[0]-seg1_p0[0], seg1_p1[1]-seg1_p0[1]]\n",
+    "    p = [seg1_p0[0], seg1_p0[1]]\n",
+    "    #normal straight through intersection\n",
+    "    r_pr = [r[1], -r[0]]\n",
+    "    q = [intersection[0], intersection[1]]\n",
+    "    crossing = intersect_straights(p, r, q, r_pr)\n",
+    "    if crossing == None:\n",
+    "        return None\n",
+    "    if math.isclose(r[0], 0.) or math.isclose(r[1], 0.):\n",
+    "        print(\"PAHD_ERROR: Method needs extension, zero component in direction vector.\")\n",
+    "        return None\n",
+    "    t0 = (crossing[0] - p[0]) / r[0]\n",
+    "    t1 = (crossing[1] - p[1]) / r[1]\n",
+    "    if not math.isclose(t0, t1):\n",
+    "        print(\"PAHD_ERROR: Parameters are not the same.\")\n",
+    "        return None\n",
+    "    if not t0 >= 0. and t0 <= 1.:\n",
+    "        print(\"PAHD_INFO: Crossing is not above segment\")\n",
+    "        return None\n",
+    "    projection = [p[0] + t0 * r[0], p[1] + t0 * r[1]]\n",
+    "    return [crossing[0] + 0.5 * (intersection[0] - crossing[0]), crossing[1] + 0.5 * (intersection[1] - crossing[1])]\n",
+    "\n",
+    "def get_new_node(seg0_p0, seg0_p1, seg2_p0, seg2_p1):\n",
+    "    intersection = intersect_segments(seg0_p0, seg0_p1, seg2_p0, seg2_p1)\n",
+    "    if intersection == None:\n",
+    "        return None\n",
+    "    return point_at_half_distance(seg0_p1, seg2_p0, intersection)\n",
+    "\n",
+    "def get_slope_delta(seg0_p0, seg0_p1, seg1_p1):\n",
+    "    if math.isclose(seg0_p1[0] - seg0_p0[0], 0.):\n",
+    "        print(\"GSD_ERROR: Infinite slope encountered.\")\n",
+    "        return 0.\n",
+    "    if math.isclose(seg1_p1[0] - seg0_p1[0], 0.):\n",
+    "        print(\"GSD_ERROR: Infinite slope encountered.\")\n",
+    "        return 0.\n",
+    "    m0 = (seg0_p1[1] - seg0_p0[1]) / (seg0_p1[0] - seg0_p0[0])\n",
+    "    m1 = (seg1_p1[1] - seg0_p1[1]) / (seg1_p1[0] - seg0_p1[0])\n",
+    "    return abs(m0-m1)\n",
+    "def get_angle_delta(seg0_p0, seg0_p1, seg1_p1, i=-1):\n",
+    "    v = [seg0_p1[0] - seg0_p0[0], seg0_p1[1] - seg0_p0[1]]\n",
+    "    w = [seg1_p1[0] - seg0_p1[0], seg1_p1[1] - seg0_p1[1]]\n",
+    "    sp = v[0] * w[0] + v[1] * w[1]\n",
+    "    sp /= np.sqrt(v[0] * v[0] + v[1] * v[1]) * np.sqrt(w[0] * w[0] + w[1] * w[1])\n",
+    "    angle = np.arccos(sp) * 180 / np.pi\n",
+    "    if(i != -1):\n",
+    "        print(f\"i: {i}, v: {v}, w: {w}, sp: {sp}\")\n",
+    "        print(f\"p0: {seg0_p0}, p1: {seg0_p1}, p2: {seg1_p1}\")\n",
+    "    return angle"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def plot_hole_indexed(hole, labels=None):\n",
+    "    xs = []\n",
+    "    ys = []\n",
+    "    ind = []\n",
+    "    index = 0\n",
+    "    for h in hole:\n",
+    "        xs.append(h[0])\n",
+    "        ys.append(h[1])\n",
+    "        ind.append(index)\n",
+    "        index += 1\n",
+    "    if labels != None:\n",
+    "        if len(labels) != len(xs):\n",
+    "            print(\"PHI_ERROR: Not each node has a label.\")\n",
+    "    fig, ax = plt.subplots(1, 1)\n",
+    "    ax.axis('equal')\n",
+    "    ax.plot(xs,ys)\n",
+    "    ax.scatter(xs,ys,c='r')\n",
+    "    for i in range(len(xs)):\n",
+    "        if labels == None or len(labels) != len(xs):\n",
+    "            ax.text(xs[i], ys[i], f\"{i}\")\n",
+    "        else:\n",
+    "            #ax.text(xs[i], ys[i], f\"{labels[i]:.2f} ({xs[i]:.4f},{ys[i]:.4f})\")\n",
+    "            ax.text(xs[i], ys[i], f\"{i}: {labels[i]:.2f}\")\n",
+    "    fig.show()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 42,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "hx = holes[0][0]\n",
+    "hy = holes[0][1]\n",
+    "hole = []\n",
+    "for i in range(len(hx)):\n",
+    "    hole.append([hx[i], hy[i]])\n",
+    "\n",
+    "#Get slope deltas\n",
+    "slope_deltas = [0]\n",
+    "for i in range(len(hole)-2):\n",
+    "    #print(f\"{i+1}: {get_slope_delta(hole[i], hole[i+1], hole[i+2])}\")\n",
+    "    slope_deltas.append(get_slope_delta(hole[i], hole[i+1], hole[i+2]))\n",
+    "slope_deltas.append(0)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "%matplotlib notebook\n",
+    "plot_hole_indexed(hole, slope_deltas)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 44,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "PAHD_INFO: Crossing is not above segment\n",
+      "PAHD_INFO: Crossing is not above segment\n",
+      "PAHD_INFO: Crossing is not above segment\n",
+      "New hole: 155\n",
+      "Old hole: 81\n"
+     ]
+    }
+   ],
+   "source": [
+    "#refine once\n",
+    "new_hole = []\n",
+    "new_hole.append(hole[0])\n",
+    "new_hole.append(hole[1])\n",
+    "index = 2\n",
+    "while index < len(hole) - 1:\n",
+    "    new_node = get_new_node(new_hole[-2], new_hole[-1], hole[index], hole[index+1])\n",
+    "    if(new_node != None):\n",
+    "        new_hole.append(new_node)\n",
+    "    new_hole.append(hole[index])\n",
+    "    index += 1\n",
+    "print(f\"New hole: {len(new_hole)}\")\n",
+    "print(f\"Old hole: {len(hole)}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 45,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "slope_deltas_new = [0]\n",
+    "for i in range(len(new_hole)-2):\n",
+    "    #print(f\"{i+1}: {get_slope_delta(hole[i], hole[i+1], hole[i+2])}\")\n",
+    "    slope_deltas_new.append(get_slope_delta(new_hole[i], new_hole[i+1], new_hole[i+2]))\n",
+    "slope_deltas_new.append(0)\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 46,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "%matplotlib notebook\n",
+    "plot_hole_indexed(new_hole, slope_deltas_new)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 47,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "%matplotlib notebook\n",
+    "plot_hole_indexed(hole, slope_deltas)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Smoothening via splines"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Number Old/New Nodes: 81/501\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Old: 81\n",
+      "New: 501\n",
+      "Maximum angle delta old: 43.40° at node 14\n",
+      "Maximum angle delta smoothed: 19.66° at node 84\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "from scipy import interpolate\n",
+    "tck, u = interpolate.splprep([holes[0][0], holes[0][1]], s=0)\n",
+    "unew = np.arange(0, 1.00005, 0.002)\n",
+    "print(f\"Number Old/New Nodes: {len(holes[0][0])}/{len(unew)}\")\n",
+    "out = interpolate.splev(unew, tck)\n",
+    "%matplotlib notebook\n",
+    "fig, ax = plt.subplots(1, 1)\n",
+    "ax.axis('equal')\n",
+    "ax.plot(holes[0][0], holes[0][1], 'x')\n",
+    "ax.plot(out[0], out[1], 'x:')\n",
+    "fig.show()\n",
+    "print(f\"Old: {len(holes[0][0])}\")\n",
+    "print(f\"New: {len(out[0])}\")\n",
+    "shole = []\n",
+    "for i in range(len(out[0])):\n",
+    "    shole.append([out[0][i], out[1][i]])\n",
+    "\n",
+    "#Get slope deltas\n",
+    "angle_deltas = [0]\n",
+    "for i in range(len(shole)-2):\n",
+    "    angle_deltas.append(get_angle_delta(shole[i], shole[i+1], shole[i+2]))\n",
+    "angle_deltas.append(0)\n",
+    "angle_deltas_old = [0]\n",
+    "for i in range(len(hole)-2):\n",
+    "    angle_deltas_old.append(get_angle_delta(hole[i], hole[i+1], hole[i+2]))\n",
+    "angle_deltas_old.append(0)\n",
+    "print(f\"Maximum angle delta old: {np.max(angle_deltas_old):.2f}° at node {np.argmax(angle_deltas_old)}\")\n",
+    "print(f\"Maximum angle delta smoothed: {np.max(angle_deltas):.2f}° at node {np.argmax(angle_deltas)}\")\n",
+    "plot_hole_indexed(shole, angle_deltas)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 49,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0.09160548840938904"
+      ]
+     },
+     "execution_count": 49,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "np.tan(5.234*np.pi/180.)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 50,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def expand_points(x, y, num=20):\n",
+    "    retx = []\n",
+    "    rety = []\n",
+    "    ks = np.linspace(0,1,num)\n",
+    "    for i in range(len(x)-1):\n",
+    "        for k in ks:\n",
+    "            retx.append(x[i]*(1.-k) + x[i+1]*k)\n",
+    "            rety.append(y[i]*(1.-k) + y[i+1]*k)\n",
+    "    return retx, rety"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 51,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def hole_to_SC_curves(finalHoleX, finalHoleY, filename, num_holes=36):\n",
+    "    holes = []\n",
+    "    angle = 0.\n",
+    "    dangle = 360. / num_holes\n",
+    "    while angle < 359.99:\n",
+    "        newXs = []\n",
+    "        newYs = []\n",
+    "        for i in range(len(finalHoleX)):\n",
+    "            p = rot([finalHoleX[i], finalHoleY[i]], angle)\n",
+    "            newXs.append(p[0])\n",
+    "            newYs.append(p[1])\n",
+    "        holes.append([newXs, newYs])\n",
+    "        angle += dangle\n",
+    "    SC_curves(holes, filename)\n",
+    "    #check min arm width\n",
+    "    if num_holes > 1:\n",
+    "        x0,y0 = expand_points(holes[0][0], holes[0][1])\n",
+    "        x1,y1 = expand_points(holes[1][0], holes[1][1])\n",
+    "        mindist = 1000.\n",
+    "        for i in range(len(x0)):\n",
+    "            for j in range(len(x1)):\n",
+    "                if(np.sqrt((x0[i]-x1[j])**2 + (y0[i]-y1[j])**2) < mindist):\n",
+    "                    mindist = np.sqrt((x0[i]-x1[j])**2 + (y0[i]-y1[j])**2)\n",
+    "        print(f\"Minimum Arm Width: {mindist*1000:.2f} um\")\n",
+    "    fig,ax = plt.subplots(1,1)\n",
+    "    for h in holes:\n",
+    "        ax.plot(h[0], h[1], '-', c='b')\n",
+    "    circt = np.linspace(0.,2.*np.pi, 100)\n",
+    "    ax.plot(1.05*np.sin(circt)/2., 1.05*np.cos(circt)/2., '-', c='r')\n",
+    "    return fig,ax"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 52,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 4.39 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "(<Figure size 432x288 with 1 Axes>, <AxesSubplot:>)"
+      ]
+     },
+     "execution_count": 52,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "hole_to_SC_curves(out[0], out[1], 'polylines_spline.txt')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Generate Drum With Fewer Arms"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 53,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 308.64 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "hole_to_SC_curves(out[0], out[1], 'polylines_spline_6holes.txt', 6)[0].show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Generate command block codes"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 54,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import numpy as np\n",
+    "def sys_block(total_thickness, num_layers, num_pts=3, offset=\"bottom\"):\n",
+    "    layer_thickness = total_thickness / num_layers\n",
+    "    layer_code = f\"secdata,{layer_thickness},1,0,{num_pts}\\n\"\n",
+    "    layer_code += f\"secoffset,{offset}\\n\"\n",
+    "    code = \"et,matid,281\\n\"\n",
+    "    code += \"sdelete,1,1\\n\"\n",
+    "    code += \"sectype,1,shell\\n\"\n",
+    "    for i in range(num_layers):\n",
+    "        code += layer_code\n",
+    "    code += \"slist,,,,brief\\n\"\n",
+    "    code += \"mplist,all\\n\"\n",
+    "    return code\n",
+    "def sol_block(num_layers, max_stress, min_stress = 0.):\n",
+    "    stresses = np.linspace(min_stress, max_stress, num_layers)\n",
+    "    code = \"\"\n",
+    "    for i in range(num_layers):\n",
+    "        code += f\"inistate,define,,,{i+1},,{stresses[i]},{stresses[i]},0\\n\"\n",
+    "    return code"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 55,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "---------------------\n",
+      "SYS\n",
+      "---------------------\n",
+      "\n",
+      "et,matid,281\n",
+      "sdelete,1,1\n",
+      "sectype,1,shell\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "secdata,1.1904761904761905e-05,1,0,3\n",
+      "secoffset,bottom\n",
+      "slist,,,,brief\n",
+      "mplist,all\n",
+      "\n",
+      "---------------------\n",
+      "SOL\n",
+      "---------------------\n",
+      "\n",
+      "inistate,define,,,1,,0.0,0.0,0\n",
+      "inistate,define,,,2,,2.4390243902439024,2.4390243902439024,0\n",
+      "inistate,define,,,3,,4.878048780487805,4.878048780487805,0\n",
+      "inistate,define,,,4,,7.317073170731707,7.317073170731707,0\n",
+      "inistate,define,,,5,,9.75609756097561,9.75609756097561,0\n",
+      "inistate,define,,,6,,12.195121951219512,12.195121951219512,0\n",
+      "inistate,define,,,7,,14.634146341463413,14.634146341463413,0\n",
+      "inistate,define,,,8,,17.073170731707318,17.073170731707318,0\n",
+      "inistate,define,,,9,,19.51219512195122,19.51219512195122,0\n",
+      "inistate,define,,,10,,21.95121951219512,21.95121951219512,0\n",
+      "inistate,define,,,11,,24.390243902439025,24.390243902439025,0\n",
+      "inistate,define,,,12,,26.829268292682926,26.829268292682926,0\n",
+      "inistate,define,,,13,,29.268292682926827,29.268292682926827,0\n",
+      "inistate,define,,,14,,31.70731707317073,31.70731707317073,0\n",
+      "inistate,define,,,15,,34.146341463414636,34.146341463414636,0\n",
+      "inistate,define,,,16,,36.58536585365854,36.58536585365854,0\n",
+      "inistate,define,,,17,,39.02439024390244,39.02439024390244,0\n",
+      "inistate,define,,,18,,41.46341463414634,41.46341463414634,0\n",
+      "inistate,define,,,19,,43.90243902439024,43.90243902439024,0\n",
+      "inistate,define,,,20,,46.34146341463415,46.34146341463415,0\n",
+      "inistate,define,,,21,,48.78048780487805,48.78048780487805,0\n",
+      "inistate,define,,,22,,51.21951219512195,51.21951219512195,0\n",
+      "inistate,define,,,23,,53.65853658536585,53.65853658536585,0\n",
+      "inistate,define,,,24,,56.09756097560975,56.09756097560975,0\n",
+      "inistate,define,,,25,,58.536585365853654,58.536585365853654,0\n",
+      "inistate,define,,,26,,60.97560975609756,60.97560975609756,0\n",
+      "inistate,define,,,27,,63.41463414634146,63.41463414634146,0\n",
+      "inistate,define,,,28,,65.85365853658537,65.85365853658537,0\n",
+      "inistate,define,,,29,,68.29268292682927,68.29268292682927,0\n",
+      "inistate,define,,,30,,70.73170731707317,70.73170731707317,0\n",
+      "inistate,define,,,31,,73.17073170731707,73.17073170731707,0\n",
+      "inistate,define,,,32,,75.60975609756098,75.60975609756098,0\n",
+      "inistate,define,,,33,,78.04878048780488,78.04878048780488,0\n",
+      "inistate,define,,,34,,80.48780487804878,80.48780487804878,0\n",
+      "inistate,define,,,35,,82.92682926829268,82.92682926829268,0\n",
+      "inistate,define,,,36,,85.36585365853658,85.36585365853658,0\n",
+      "inistate,define,,,37,,87.80487804878048,87.80487804878048,0\n",
+      "inistate,define,,,38,,90.24390243902438,90.24390243902438,0\n",
+      "inistate,define,,,39,,92.6829268292683,92.6829268292683,0\n",
+      "inistate,define,,,40,,95.1219512195122,95.1219512195122,0\n",
+      "inistate,define,,,41,,97.5609756097561,97.5609756097561,0\n",
+      "inistate,define,,,42,,100.0,100.0,0\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "thickness = 0.0005 # mm\n",
+    "layers = 42\n",
+    "max_stress = 100 # MPa\n",
+    "min_stress = 0 #MPa\n",
+    "print(\"---------------------\\nSYS\\n---------------------\\n\")\n",
+    "print(sys_block(thickness, layers))\n",
+    "print(\"---------------------\\nSOL\\n---------------------\\n\")\n",
+    "print(sol_block(layers, max_stress, min_stress))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# New Designs"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Ellipse in Tilt of Old Holes"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 56,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 5.10 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "hole_to_SC_curves(ellx, elly, 'polylines_ellipse.txt', 24)[0].show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "This leads to a deformation from 2.4 um down to -0.9 um, and a frequency of 17 kHz."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Just Circles"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 57,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Hole Center: (0.11725202718026935, 0.45779557666723186)\n",
+      "Hole Radius typically in [0.028, 0.188]\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(f\"Hole Center: ({cx}, {cy})\")\n",
+    "print(f\"Hole Radius typically in [{0.028}, {0.188}]\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 58,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 5.80 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "cx = 0.117\n",
+    "cy = 0.458\n",
+    "radius = 0.028 / 2.\n",
+    "hx = cx + radius * np.sin(np.linspace(0,2.*np.pi,50))\n",
+    "hy = cy + radius * np.cos(np.linspace(0,2.*np.pi,50))\n",
+    "hole_to_SC_curves(hx, hy, 'polylines_circle.txt', 88)[0].show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Deformation is 3 nm down to -85 nm, but the frequency is 85 kHz."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Straight Long Arms"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 59,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 5.91 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "cx = 0.117\n",
+    "cy = 0.458\n",
+    "placement_radius = np.sqrt(cx**2 + cy**2)\n",
+    "rotation_degs = 10.\n",
+    "p0 = [placement_radius, 0.]\n",
+    "p1 = [placement_radius - 0.1, 0.]\n",
+    "p2 = rot(p1,rotation_degs)\n",
+    "p3 = rot(p0,rotation_degs)\n",
+    "p4 = rot(p3,-rotation_degs + 0.1)\n",
+    "hx = [p0[0], p1[0], p2[0], p3[0], p4[0]]\n",
+    "hy = [p0[1], p1[1], p2[1], p3[1], p4[1]]\n",
+    "hole_to_SC_curves(hx, hy, 'polylines_straight.txt', 33)[0].show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Deformation is 360 nm down to -40 nm. The frequency is reduced to 50 kHz by reducing the drum radius by 40 nm."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Fat Straight Long Arms"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 60,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 21.68 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "cx = 0.117\n",
+    "cy = 0.458\n",
+    "placement_radius = np.sqrt(cx**2 + cy**2)\n",
+    "rotation_degs = 10.\n",
+    "p0 = [placement_radius, 0.]\n",
+    "p1 = [placement_radius - 0.1, 0.]\n",
+    "p2 = rot(p1,rotation_degs)\n",
+    "p3 = rot(p0,rotation_degs)\n",
+    "p4 = rot(p3,-rotation_degs + 0.1)\n",
+    "hx = [p0[0], p1[0], p2[0], p3[0], p4[0]]\n",
+    "hy = [p0[1], p1[1], p2[1], p3[1], p4[1]]\n",
+    "hole_to_SC_curves(hx, hy, 'polylines_straight_fat.txt', 27)[0].show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Deformation is 0 down to -296 nm, with a frequency of 69 kHz."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Straight Long Arms with Holes"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 61,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 25.23 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbAAAAEgCAYAAADVKCZpAAAK20lEQVR4Xu3VgQkAAAgCwdx/6eZ4uCaQM3DnCBAgQIBAUGDBzCITIECAAIEzYJ6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECDzIbwEhPy/9RgAAAABJRU5ErkJggg==\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "cx = 0.117\n",
+    "cy = 0.458\n",
+    "placement_radius = np.sqrt(cx**2 + cy**2)\n",
+    "rotation_degs = 10.\n",
+    "#p0 = [placement_radius, 0.]\n",
+    "#p1 = [placement_radius - 0.1, 0.]\n",
+    "#p2 = rot(p1,rotation_degs)\n",
+    "#p3 = rot(p0,rotation_degs)\n",
+    "#p4 = rot(p3,-rotation_degs + 0.1)\n",
+    "#hx = [p0[0], p1[0], p2[0], p3[0], p4[0]]\n",
+    "#hy = [p0[1], p1[1], p2[1], p3[1], p4[1]]\n",
+    "#hole_to_SC_curves(hx, hy, 'polylines_straight.txt', 33)[0].show()\n",
+    "\n",
+    "#holes\n",
+    "cr = 0.02\n",
+    "cx = placement_radius - 0.1 - 1.5*cr\n",
+    "cy = 0\n",
+    "circle_center = rot([cx,cy],rotation_degs/2.)\n",
+    "cx = circle_center[0] + cr * np.sin(np.linspace(0.,2.*np.pi,50))\n",
+    "cy = circle_center[1] + cr * np.cos(np.linspace(0.,2.*np.pi,50))\n",
+    "hole_to_SC_curves(cx, cy, 'polylines_circleholes.txt', 33)[0].show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Deformation 27 nm down to -368 nm. Frequency 50 kHz"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Central Hole"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 62,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "radius = 0.05\n",
+    "circ_x = radius*np.sin(np.linspace(0,2.*np.pi,50))\n",
+    "circ_y = radius*np.cos(np.linspace(0,2.*np.pi,50))\n",
+    "hole_to_SC_curves(circ_x, circ_y, 'polylines_centralhole.txt', 1)[0].show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Deformation 0 down to -198 nm. Frequency 94 kHz."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Holes throughout"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 63,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "filename = \"polylines_holesthroughout.txt\"\n",
+    "radius = 0.01\n",
+    "holes = []\n",
+    "\n",
+    "x = -0.5\n",
+    "while x <= 0.5:\n",
+    "    y = -0.5\n",
+    "    while y < 0.5:\n",
+    "        if np.sqrt(x**2 + y**2) + radius < 0.5:\n",
+    "            cx = x + radius * np.sin(np.linspace(0,2.*np.pi,20))\n",
+    "            cy = y + radius * np.cos(np.linspace(0,2.*np.pi,20))\n",
+    "            holes.append([cx,cy])\n",
+    "        y += 6. * radius\n",
+    "    x += 6. * radius\n",
+    "SC_curves(holes, filename)\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "for h in holes:\n",
+    "    ax.plot(h[0], h[1], '-', c='b')\n",
+    "circt = np.linspace(0.,2.*np.pi, 100)\n",
+    "ax.plot(1.05*np.sin(circt)/2., 1.05*np.cos(circt)/2., '-', c='r')\n",
+    "plt.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Deformation 0.04 nm down to -57 nm. Frequency 89.8 kHz"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Perforated drum in smaller region"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 64,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "filename = \"polylines_perforated.txt\"\n",
+    "radius = 0.01\n",
+    "holes = []\n",
+    "\n",
+    "x = -0.5\n",
+    "while x <= 0.5:\n",
+    "    y = -0.5\n",
+    "    while y < 0.5:\n",
+    "        if np.sqrt(x**2 + y**2) + radius < 0.43:\n",
+    "            cx = x + radius * np.sin(np.linspace(0,2.*np.pi,20))\n",
+    "            cy = y + radius * np.cos(np.linspace(0,2.*np.pi,20))\n",
+    "            holes.append([cx,cy])\n",
+    "        y += 6. * radius\n",
+    "    x += 6. * radius\n",
+    "SC_curves(holes, filename)\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "for h in holes:\n",
+    "    ax.plot(h[0], h[1], '-', c='b')\n",
+    "circt = np.linspace(0.,2.*np.pi, 100)\n",
+    "ax.plot(1.05*np.sin(circt)/2., 1.05*np.cos(circt)/2., '-', c='r')\n",
+    "plt.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Design Alteration V1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 65,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(filterX, filterY)\n",
+    "for i in range(len(filterX)):\n",
+    "    ax.text(filterX[i], filterY[i], f\"{i}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 66,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 4.38 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbAAAAEgCAYAAADVKCZpAAAK20lEQVR4Xu3VgQkAAAgCwdx/6eZ4uCaQM3DnCBAgQIBAUGDBzCITIECAAIEzYJ6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECDzIbwEhPy/9RgAAAABJRU5ErkJggg==\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "(<Figure size 432x288 with 1 Axes>, <AxesSubplot:>)"
+      ]
+     },
+     "execution_count": 66,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "filename = \"design_v1.txt\"\n",
+    "hole_to_SC_curves(filterX, filterY, filename, num_holes=36)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "I want to cut the drums by dropping points 28-39, such that point 27 directly connects to point 40."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 67,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "filteredX = np.concatenate((filterX[0:28], filterX[40:]))\n",
+    "filteredY = np.concatenate((filterY[0:28], filterY[40:]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 68,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 4.38 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "(<Figure size 432x288 with 1 Axes>, <AxesSubplot:>)"
+      ]
+     },
+     "execution_count": 68,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "filename = \"design_v1.txt\"\n",
+    "hole_to_SC_curves(filteredX, filteredY, filename, num_holes=36)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Design Alteration V1 larger cutout"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 69,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "filteredX = np.concatenate((filterX[0:24], filterX[42:]))\n",
+    "filteredY = np.concatenate((filterY[0:24], filterY[42:]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 70,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 1.79 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "(<Figure size 432x288 with 1 Axes>, <AxesSubplot:>)"
+      ]
+     },
+     "execution_count": 70,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "filename = \"design_v1l.txt\"\n",
+    "hole_to_SC_curves(filteredX, filteredY, filename, num_holes=36)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "This works, the arms deform by 150 nm while the drum deforms by less than 2 nm."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Design Alteration V1 larger cutout 2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 71,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "filtereddX = np.concatenate((filterX[0:24], filterX[41:]))\n",
+    "filtereddY = np.concatenate((filterY[0:24], filterY[41:]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 72,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 2.81 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "(<Figure size 432x288 with 1 Axes>, <AxesSubplot:>)"
+      ]
+     },
+     "execution_count": 72,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "filename = \"design_v1l2.txt\"\n",
+    "hole_to_SC_curves(filtereddX, filtereddY, filename, num_holes=36)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 73,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def compare_designs(x0,y0,x1,y1):\n",
+    "    fig,ax = plt.subplots(1,1)\n",
+    "    ax.plot(x0,y0, c='r')\n",
+    "    ax.plot(x1,y1, c='b')\n",
+    "    for i in range(len(x0)):\n",
+    "        x0[i], y0[i] = rot([x0[i],y0[i]],10)\n",
+    "        x1[i], y1[i] = rot([x1[i],y1[i]],10)\n",
+    "    ax.plot(x0,y0, c='r')\n",
+    "    ax.plot(x1,y1, c='b')\n",
+    "    ax.set_aspect('equal')\n",
+    "    fig.show()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 74,
+   "metadata": {
+    "scrolled": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "compare_designs(filteredX,filteredY,filtereddX,filtereddY)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Doesn't work, deformation is back to several micrometers."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Design Alteration V1, constant arm thickness"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 75,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5ebdaed60>]"
+      ]
+     },
+     "execution_count": 75,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "import copy\n",
+    "drx = copy.deepcopy(filterX)\n",
+    "dry = copy.deepcopy(filterY)\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(drx, dry)\n",
+    "for i in range(len(drx)):\n",
+    "    ax.text(drx[i], dry[i], f\"{i}\")\n",
+    "\n",
+    "x0 = []\n",
+    "y0 = []\n",
+    "for i in range(len(drx)):\n",
+    "    x0n, y0n = rot([drx[i],dry[i]],10)\n",
+    "    x0.append(x0n)\n",
+    "    y0.append(y0n)\n",
+    "for i in range(len(x0)):\n",
+    "    ax.text(x0[i], y0[i], f\"{i}\")\n",
+    "ax.plot(x0,y0)\n",
+    "\n",
+    "def const_dist_pt(p0, p1, p2, dist):\n",
+    "    p0n = np.array(p0)\n",
+    "    p1n = np.array(p1)\n",
+    "    p2n = np.array(p2)\n",
+    "    dir = p2n - p0n\n",
+    "    dir /= np.sqrt(dir[0]**2 + dir[1]**2)\n",
+    "    dir[0],dir[1] = -dir[1],dir[0]\n",
+    "    return p1 + dir*dist\n",
+    "    \n",
+    "nc_x = [drx[76]]\n",
+    "nc_y = [dry[76]]\n",
+    "for i in range(47,25,-1):\n",
+    "    nv = const_dist_pt([x0[i+1],y0[i+1]], [x0[i],y0[i]], [x0[i-1],y0[i-1]], 4.38e-3)\n",
+    "    nc_x.append(nv[0])\n",
+    "    nc_y.append(nv[1])\n",
+    "\n",
+    "ax.plot(nc_x, nc_y, 'x')\n",
+    "\n",
+    "#spline to connect to old hole\n",
+    "n = len(nc_x)\n",
+    "tck, u = interpolate.splprep([[nc_x[n-3],nc_x[n-2],nc_x[n-1],drx[21],drx[22]], [nc_y[n-3],nc_y[n-2],nc_y[n-1],dry[21],dry[22]]], s=0)\n",
+    "unew = np.arange(0, 1.00005, 0.05)\n",
+    "out = interpolate.splev(unew, tck)\n",
+    "ax.plot(out[0], out[1], 'x')\n",
+    "\n",
+    "new_hole_x = np.concatenate((nc_x[5:], out[0][4:-1], drx[23:76], nc_x[:5]))\n",
+    "new_hole_y = np.concatenate((nc_y[5:], out[1][4:-1], dry[23:76], nc_y[:5]))\n",
+    "\n",
+    "ax.plot(new_hole_x, new_hole_y, '*')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 76,
+   "metadata": {
+    "scrolled": false
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 4.38 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "(<Figure size 432x288 with 1 Axes>, <AxesSubplot:>)"
+      ]
+     },
+     "execution_count": 76,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "filename = \"design_v1l3.txt\"\n",
+    "hole_to_SC_curves(new_hole_x, new_hole_y, filename, num_holes=36)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Doesn't work, 3.4 um down to -1.3 um"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Design Alteration V1, constant arm thickness thinner"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 77,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "C:\\Users\\engel\\AppData\\Local\\Temp/ipykernel_21064/3497237966.py:4: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).\n",
+      "  fig,ax = plt.subplots(1,1)\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5ebfd9250>]"
+      ]
+     },
+     "execution_count": 77,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "import copy\n",
+    "drx = copy.deepcopy(filterX)\n",
+    "dry = copy.deepcopy(filterY)\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(drx, dry)\n",
+    "for i in range(len(drx)):\n",
+    "    ax.text(drx[i], dry[i], f\"{i}\")\n",
+    "\n",
+    "x0 = []\n",
+    "y0 = []\n",
+    "for i in range(len(drx)):\n",
+    "    x0n, y0n = rot([drx[i],dry[i]],10)\n",
+    "    x0.append(x0n)\n",
+    "    y0.append(y0n)\n",
+    "for i in range(len(x0)):\n",
+    "    ax.text(x0[i], y0[i], f\"{i}\")\n",
+    "ax.plot(x0,y0)\n",
+    "\n",
+    "def const_dist_pt(p0, p1, p2, dist):\n",
+    "    p0n = np.array(p0)\n",
+    "    p1n = np.array(p1)\n",
+    "    p2n = np.array(p2)\n",
+    "    dir = p2n - p0n\n",
+    "    dir /= np.sqrt(dir[0]**2 + dir[1]**2)\n",
+    "    dir[0],dir[1] = -dir[1],dir[0]\n",
+    "    return p1 + dir*dist\n",
+    "    \n",
+    "nc_x = [drx[76]]\n",
+    "nc_y = [dry[76]]\n",
+    "for i in range(47,25,-1):\n",
+    "    nv = const_dist_pt([x0[i+1],y0[i+1]], [x0[i],y0[i]], [x0[i-1],y0[i-1]], 4.38e-3/2)\n",
+    "    nc_x.append(nv[0])\n",
+    "    nc_y.append(nv[1])\n",
+    "\n",
+    "ax.plot(nc_x, nc_y, 'x')\n",
+    "\n",
+    "#spline to connect to old hole\n",
+    "n = len(nc_x)\n",
+    "tck, u = interpolate.splprep([[nc_x[n-3],nc_x[n-2],nc_x[n-1],drx[21],drx[22]], [nc_y[n-3],nc_y[n-2],nc_y[n-1],dry[21],dry[22]]], s=0)\n",
+    "unew = np.arange(0, 1.00005, 0.05)\n",
+    "out = interpolate.splev(unew, tck)\n",
+    "ax.plot(out[0], out[1], 'x')\n",
+    "\n",
+    "new_hole_x = np.concatenate((nc_x[5:], out[0][4:-1], drx[23:76], nc_x[:5]))\n",
+    "new_hole_y = np.concatenate((nc_y[5:], out[1][4:-1], dry[23:76], nc_y[:5]))\n",
+    "\n",
+    "ax.plot(new_hole_x, new_hole_y, '*')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 78,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "plt.close('all')\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.plot(new_hole_x,new_hole_y, '*')\n",
+    "for i in range(len(new_hole_x)):\n",
+    "    ax.text(new_hole_x[i], new_hole_y[i], f\"{i}\")\n",
+    "ax.set_aspect('equal')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 79,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "new_hole_x = np.concatenate((new_hole_x[:84], new_hole_x[88:]))\n",
+    "new_hole_y = np.concatenate((new_hole_y[:84], new_hole_y[88:]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 80,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 2.19 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "(<Figure size 432x288 with 1 Axes>, <AxesSubplot:>)"
+      ]
+     },
+     "execution_count": 80,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "filename = \"design_v1l4.txt\"\n",
+    "hole_to_SC_curves(new_hole_x, new_hole_y, filename, num_holes=36)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Design Alteration V1, constant arm thickness as thin as minimum when it worked"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 81,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5ec6f01c0>]"
+      ]
+     },
+     "execution_count": 81,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "import copy\n",
+    "drx = copy.deepcopy(filterX)\n",
+    "dry = copy.deepcopy(filterY)\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(drx, dry)\n",
+    "for i in range(len(drx)):\n",
+    "    ax.text(drx[i], dry[i], f\"{i}\")\n",
+    "\n",
+    "x0 = []\n",
+    "y0 = []\n",
+    "for i in range(len(drx)):\n",
+    "    x0n, y0n = rot([drx[i],dry[i]],10)\n",
+    "    x0.append(x0n)\n",
+    "    y0.append(y0n)\n",
+    "for i in range(len(x0)):\n",
+    "    ax.text(x0[i], y0[i], f\"{i}\")\n",
+    "ax.plot(x0,y0)\n",
+    "\n",
+    "def const_dist_pt(p0, p1, p2, dist):\n",
+    "    p0n = np.array(p0)\n",
+    "    p1n = np.array(p1)\n",
+    "    p2n = np.array(p2)\n",
+    "    dir = p2n - p0n\n",
+    "    dir /= np.sqrt(dir[0]**2 + dir[1]**2)\n",
+    "    dir[0],dir[1] = -dir[1],dir[0]\n",
+    "    return p1 + dir*dist\n",
+    "    \n",
+    "nc_x = [drx[76]]\n",
+    "nc_y = [dry[76]]\n",
+    "for i in range(47,25,-1):\n",
+    "    nv = const_dist_pt([x0[i+1],y0[i+1]], [x0[i],y0[i]], [x0[i-1],y0[i-1]], 1.79e-3)\n",
+    "    nc_x.append(nv[0])\n",
+    "    nc_y.append(nv[1])\n",
+    "\n",
+    "ax.plot(nc_x, nc_y, 'x')\n",
+    "\n",
+    "#spline to connect to old hole\n",
+    "n = len(nc_x)\n",
+    "tck, u = interpolate.splprep([[nc_x[n-3],nc_x[n-2],nc_x[n-1],drx[21],drx[22]], [nc_y[n-3],nc_y[n-2],nc_y[n-1],dry[21],dry[22]]], s=0)\n",
+    "unew = np.arange(0, 1.00005, 0.05)\n",
+    "out = interpolate.splev(unew, tck)\n",
+    "ax.plot(out[0], out[1], 'x')\n",
+    "\n",
+    "new_hole_x = np.concatenate((nc_x[5:], out[0][4:-1], drx[23:76], nc_x[:5]))\n",
+    "new_hole_y = np.concatenate((nc_y[5:], out[1][4:-1], dry[23:76], nc_y[:5]))\n",
+    "\n",
+    "ax.plot(new_hole_x, new_hole_y, '*')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 82,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbAAAAEgCAYAAADVKCZpAAAK20lEQVR4Xu3VgQkAAAgCwdx/6eZ4uCaQM3DnCBAgQIBAUGDBzCITIECAAIEzYJ6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECDzIbwEhPy/9RgAAAABJRU5ErkJggg==\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "plt.close('all')\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.plot(new_hole_x,new_hole_y, '*')\n",
+    "for i in range(len(new_hole_x)):\n",
+    "    ax.text(new_hole_x[i], new_hole_y[i], f\"{i}\")\n",
+    "ax.set_aspect('equal')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 83,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "new_hole_x = np.concatenate((new_hole_x[:84], new_hole_x[88:]))\n",
+    "new_hole_y = np.concatenate((new_hole_y[:84], new_hole_y[88:]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 84,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 1.79 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "(<Figure size 432x288 with 1 Axes>, <AxesSubplot:>)"
+      ]
+     },
+     "execution_count": 84,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "filename = \"design_v1l5.txt\"\n",
+    "hole_to_SC_curves(new_hole_x, new_hole_y, filename, num_holes=36)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Doesn't work, big deformation."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Design Alteration V1, constant arm thickness as thin as minimum when it worked, but shifting the other side of the drum"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 85,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5e9ce31f0>]"
+      ]
+     },
+     "execution_count": 85,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "import copy\n",
+    "drx = copy.deepcopy(filterX)\n",
+    "dry = copy.deepcopy(filterY)\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(drx, dry)\n",
+    "for i in range(len(drx)):\n",
+    "    ax.text(drx[i], dry[i], f\"{i}\")\n",
+    "\n",
+    "x0 = []\n",
+    "y0 = []\n",
+    "for i in range(len(drx)):\n",
+    "    x0n, y0n = rot([drx[i],dry[i]],-10)\n",
+    "    x0.append(x0n)\n",
+    "    y0.append(y0n)\n",
+    "for i in range(len(x0)):\n",
+    "    ax.text(x0[i], y0[i], f\"{i}\")\n",
+    "ax.plot(x0,y0)\n",
+    "\n",
+    "def const_dist_pt(p0, p1, p2, dist):\n",
+    "    p0n = np.array(p0)\n",
+    "    p1n = np.array(p1)\n",
+    "    p2n = np.array(p2)\n",
+    "    dir = p2n - p0n\n",
+    "    dir /= np.sqrt(dir[0]**2 + dir[1]**2)\n",
+    "    dir[0],dir[1] = -dir[1],dir[0]\n",
+    "    return p1 + dir*dist\n",
+    "\n",
+    "nc_x = [drx[48]]\n",
+    "nc_y = [dry[48]]\n",
+    "for i in range(76,80):\n",
+    "    nv = const_dist_pt([x0[i+1],y0[i+1]], [x0[i],y0[i]], [x0[i-1],y0[i-1]], 4.38e-3)\n",
+    "    nc_x.append(nv[0])\n",
+    "    nc_y.append(nv[1])\n",
+    "for i in range(0,12):\n",
+    "    nv = const_dist_pt([x0[i+1],y0[i+1]], [x0[i],y0[i]], [x0[i-1],y0[i-1]], 4.38e-3)\n",
+    "    nc_x.append(nv[0])\n",
+    "    nc_y.append(nv[1])\n",
+    "ax.plot(nc_x, nc_y, 'x')\n",
+    "\n",
+    "#spline to connect to old hole\n",
+    "n = len(nc_x)\n",
+    "tck, u = interpolate.splprep([[nc_x[n-3],nc_x[n-2],nc_x[n-1],drx[15],drx[14]],[nc_y[n-3],nc_y[n-2],nc_y[n-1],dry[15],dry[14]]],s=0)\n",
+    "unew = np.arange(0, 1.00005, 0.08)\n",
+    "out = interpolate.splev(unew, tck)\n",
+    "ax.plot(out[0], out[1], 'x')\n",
+    "\n",
+    "new_hole_x = np.concatenate((drx[0:15], out[0][-1:2:-1], nc_x[-1:0:-1], drx[49:]))\n",
+    "new_hole_y = np.concatenate((dry[0:15], out[1][-1:2:-1], nc_y[-1:0:-1], dry[49:]))\n",
+    "\n",
+    "#spline to connect to old hole\n",
+    "#n = len(nc_x)\n",
+    "#tck, u = interpolate.splprep([[nc_x[n-3],nc_x[n-2],nc_x[n-1],drx[21],drx[22]], [nc_y[n-3],nc_y[n-2],nc_y[n-1],dry[21],dry[22]]], s=0)\n",
+    "#unew = np.arange(0, 1.00005, 0.05)\n",
+    "#out = interpolate.splev(unew, tck)\n",
+    "#ax.plot(out[0], out[1], 'x')\n",
+    "\n",
+    "#new_hole_x = np.concatenate((nc_x[5:], out[0][4:-1], drx[23:76], nc_x[:5]))\n",
+    "#new_hole_y = np.concatenate((nc_y[5:], out[1][4:-1], dry[23:76], nc_y[:5]))\n",
+    "\n",
+    "ax.plot(new_hole_x, new_hole_y, '*')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 86,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "plt.close('all')\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.plot(new_hole_x,new_hole_y, '*')\n",
+    "for i in range(len(new_hole_x)):\n",
+    "    ax.text(new_hole_x[i], new_hole_y[i], f\"{i}\")\n",
+    "ax.set_aspect('equal')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 87,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 4.37 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "(<Figure size 432x288 with 1 Axes>, <AxesSubplot:>)"
+      ]
+     },
+     "execution_count": 87,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "filename = \"design_v1l6.txt\"\n",
+    "hole_to_SC_curves(new_hole_x, new_hole_y, filename, num_holes=36)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Doesn't work. Nothing I have done so far works."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Design Alteration V4, but with shifted bridge"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 88,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5ea49c6d0>]"
+      ]
+     },
+     "execution_count": 88,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "import copy\n",
+    "drx = copy.deepcopy(filterX)\n",
+    "dry = copy.deepcopy(filterY)\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(drx, dry)\n",
+    "for i in range(len(drx)):\n",
+    "    ax.text(drx[i], dry[i], f\"{i}\")\n",
+    "\n",
+    "x0 = []\n",
+    "y0 = []\n",
+    "for i in range(len(drx)):\n",
+    "    x0n, y0n = rot([drx[i],dry[i]],-10)\n",
+    "    x0.append(x0n)\n",
+    "    y0.append(y0n)\n",
+    "for i in range(len(x0)):\n",
+    "    ax.text(x0[i], y0[i], f\"{i}\")\n",
+    "ax.plot(x0,y0)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 89,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "[0.0834235  0.07841773 0.07347544]\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(drx[0:3])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 90,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "inner_x = np.concatenate((drx[8:19],[drx[8]+0.01*(drx[19] - drx[8])]))\n",
+    "inner_y = np.concatenate((dry[8:19],[dry[8]+0.01*(dry[19] - dry[8])]))\n",
+    "outer_x = np.concatenate((drx[20:],drx[0:7],[drx[20] - 0.01*(drx[20] - drx[7])]))\n",
+    "outer_y = np.concatenate((dry[20:],dry[0:7],[dry[20] - 0.01*(dry[20] - dry[7])]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 91,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5eb322c70>]"
+      ]
+     },
+     "execution_count": 91,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(inner_x, inner_y)\n",
+    "ax.plot(outer_x, outer_y)\n",
+    "\n",
+    "x0 = []\n",
+    "y0 = []\n",
+    "for i in range(len(inner_x)):\n",
+    "    x0n, y0n = rot([inner_x[i],inner_y[i]],-10)\n",
+    "    x0.append(x0n)\n",
+    "    y0.append(y0n)\n",
+    "ax.plot(x0,y0)\n",
+    "x0 = []\n",
+    "y0 = []\n",
+    "for i in range(len(outer_x)):\n",
+    "    x0n, y0n = rot([outer_x[i],outer_y[i]],-10)\n",
+    "    x0.append(x0n)\n",
+    "    y0.append(y0n)\n",
+    "ax.plot(x0,y0)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 92,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 63.54 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 4.38 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "(<Figure size 432x288 with 1 Axes>, <AxesSubplot:>)"
+      ]
+     },
+     "execution_count": 92,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "filename = \"design_v4_inner.txt\"\n",
+    "hole_to_SC_curves(inner_x, inner_y, filename, num_holes=36)\n",
+    "filename = \"design_v4_outer.txt\"\n",
+    "hole_to_SC_curves(outer_x, outer_y, filename, num_holes=36)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Doesn't really change anything."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Design Alteration V4r with bridge on the other side"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 93,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5eaf2ed90>]"
+      ]
+     },
+     "execution_count": 93,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "import copy\n",
+    "drx = copy.deepcopy(filterX)\n",
+    "dry = copy.deepcopy(filterY)\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(drx, dry)\n",
+    "for i in range(len(drx)):\n",
+    "    ax.text(drx[i], dry[i], f\"{i}\")\n",
+    "\n",
+    "x0 = []\n",
+    "y0 = []\n",
+    "for i in range(len(drx)):\n",
+    "    x0n, y0n = rot([drx[i],dry[i]],-10)\n",
+    "    x0.append(x0n)\n",
+    "    y0.append(y0n)\n",
+    "for i in range(len(x0)):\n",
+    "    ax.text(x0[i], y0[i], f\"{i}\")\n",
+    "ax.plot(x0,y0)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 94,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "inner_x = np.concatenate((drx[76:],drx[:33],[drx[76]+0.01*(drx[32] - drx[76])]))\n",
+    "inner_y = np.concatenate((dry[76:],dry[:33],[dry[76]+0.01*(dry[32] - dry[76])]))\n",
+    "outer_x = np.concatenate((drx[34:75],[drx[34] + 0.01*(drx[34] - drx[74])]))\n",
+    "outer_y = np.concatenate((dry[34:75],[dry[34] + 0.01*(dry[34] - dry[74])]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 95,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5ea9bd370>]"
+      ]
+     },
+     "execution_count": 95,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(inner_x, inner_y)\n",
+    "ax.plot(outer_x, outer_y)\n",
+    "\n",
+    "x0 = []\n",
+    "y0 = []\n",
+    "for i in range(len(inner_x)):\n",
+    "    x0n, y0n = rot([inner_x[i],inner_y[i]],-10)\n",
+    "    x0.append(x0n)\n",
+    "    y0.append(y0n)\n",
+    "ax.plot(x0,y0)\n",
+    "x0 = []\n",
+    "y0 = []\n",
+    "for i in range(len(outer_x)):\n",
+    "    x0n, y0n = rot([outer_x[i],outer_y[i]],-10)\n",
+    "    x0.append(x0n)\n",
+    "    y0.append(y0n)\n",
+    "ax.plot(x0,y0)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 96,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 11.43 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 4.66 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "(<Figure size 432x288 with 1 Axes>, <AxesSubplot:>)"
+      ]
+     },
+     "execution_count": 96,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "filename = \"design_v4r_inner.txt\"\n",
+    "hole_to_SC_curves(inner_x, inner_y, filename, num_holes=36)\n",
+    "filename = \"design_v4r_outer.txt\"\n",
+    "hole_to_SC_curves(outer_x, outer_y, filename, num_holes=36)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "This kinda works, 530 nm in the drum center, -380 nm in the arms"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Design Alteration V4r with bridge on the other side and an additional bridge"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 97,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5ea8087c0>]"
+      ]
+     },
+     "execution_count": 97,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "import copy\n",
+    "drx = copy.deepcopy(filterX)\n",
+    "dry = copy.deepcopy(filterY)\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(drx, dry)\n",
+    "for i in range(len(drx)):\n",
+    "    ax.text(drx[i], dry[i], f\"{i}\")\n",
+    "\n",
+    "x0 = []\n",
+    "y0 = []\n",
+    "for i in range(len(drx)):\n",
+    "    x0n, y0n = rot([drx[i],dry[i]],-10)\n",
+    "    x0.append(x0n)\n",
+    "    y0.append(y0n)\n",
+    "for i in range(len(x0)):\n",
+    "    ax.text(x0[i], y0[i], f\"{i}\")\n",
+    "ax.plot(x0,y0)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 98,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#inner stays the same\n",
+    "inner_x = np.concatenate((drx[76:],drx[:33],[drx[76]+0.01*(drx[32] - drx[76])]))\n",
+    "inner_y = np.concatenate((dry[76:],dry[:33],[dry[76]+0.01*(dry[32] - dry[76])]))\n",
+    "#outer is now two holes\n",
+    "outer_1_x = np.concatenate((drx[34:45], drx[63:75],[drx[34] + 0.01*(drx[34] - drx[74])]))\n",
+    "outer_1_y = np.concatenate((dry[34:45], dry[63:75],[dry[34] + 0.01*(dry[34] - dry[74])]))\n",
+    "outer_2_x = np.concatenate((drx[45:63], [drx[45] + 0.01*(drx[62] - drx[45])]))\n",
+    "outer_2_y = np.concatenate((dry[45:63], [dry[45] + 0.01*(dry[62] - dry[45])]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 99,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbAAAAEgCAYAAADVKCZpAAAK20lEQVR4Xu3VgQkAAAgCwdx/6eZ4uCaQM3DnCBAgQIBAUGDBzCITIECAAIEzYJ6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECDzIbwEhPy/9RgAAAABJRU5ErkJggg==\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5ec858be0>]"
+      ]
+     },
+     "execution_count": 99,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(inner_x, inner_y)\n",
+    "ax.plot(outer_1_x, outer_1_y)\n",
+    "ax.plot(outer_2_x, outer_2_y)\n",
+    "\n",
+    "x0 = []\n",
+    "y0 = []\n",
+    "for i in range(len(inner_x)):\n",
+    "    x0n, y0n = rot([inner_x[i],inner_y[i]],-10)\n",
+    "    x0.append(x0n)\n",
+    "    y0.append(y0n)\n",
+    "ax.plot(x0,y0)\n",
+    "x0 = []\n",
+    "y0 = []\n",
+    "for i in range(len(outer_1_x)):\n",
+    "    x0n, y0n = rot([outer_1_x[i],outer_1_y[i]],-10)\n",
+    "    x0.append(x0n)\n",
+    "    y0.append(y0n)\n",
+    "ax.plot(x0,y0)\n",
+    "x0 = []\n",
+    "y0 = []\n",
+    "for i in range(len(outer_2_x)):\n",
+    "    x0n, y0n = rot([outer_2_x[i],outer_2_y[i]],-10)\n",
+    "    x0.append(x0n)\n",
+    "    y0.append(y0n)\n",
+    "ax.plot(x0,y0)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 100,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 11.43 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 30.47 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 51.71 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbAAAAEgCAYAAADVKCZpAAAK20lEQVR4Xu3VgQkAAAgCwdx/6eZ4uCaQM3DnCBAgQIBAUGDBzCITIECAAIEzYJ6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECDzIbwEhPy/9RgAAAABJRU5ErkJggg==\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "(<Figure size 432x288 with 1 Axes>, <AxesSubplot:>)"
+      ]
+     },
+     "execution_count": 100,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "filename = \"design_v4r_inner.txt\"\n",
+    "hole_to_SC_curves(inner_x, inner_y, filename, num_holes=36)\n",
+    "filename = \"design_v4r_outer_1.txt\"\n",
+    "hole_to_SC_curves(outer_1_x, outer_1_y, filename, num_holes=36)\n",
+    "filename = \"design_v4r_outer_2.txt\"\n",
+    "hole_to_SC_curves(outer_2_x, outer_2_y, filename, num_holes=36)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Design Alteration V4rd, but with smoothed edges"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 101,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5eb42c1f0>]"
+      ]
+     },
+     "execution_count": 101,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "import copy\n",
+    "drx = copy.deepcopy(filterX)\n",
+    "dry = copy.deepcopy(filterY)\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(drx, dry)\n",
+    "for i in range(len(drx)):\n",
+    "    ax.text(drx[i], dry[i], f\"{i}\")\n",
+    "\n",
+    "x0 = []\n",
+    "y0 = []\n",
+    "for i in range(len(drx)):\n",
+    "    x0n, y0n = rot([drx[i],dry[i]],-10)\n",
+    "    x0.append(x0n)\n",
+    "    y0.append(y0n)\n",
+    "for i in range(len(x0)):\n",
+    "    ax.text(x0[i], y0[i], f\"{i}\")\n",
+    "ax.plot(x0,y0)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 102,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#inner stays the same\n",
+    "inner_x = np.concatenate((drx[76:],drx[:33],[drx[76]+0.01*(drx[32] - drx[76])]))\n",
+    "inner_y = np.concatenate((dry[76:],dry[:33],[dry[76]+0.01*(dry[32] - dry[76])]))\n",
+    "#outer is now two holes\n",
+    "outer_1_x = np.concatenate((drx[34:45], drx[63:75],[drx[34] + 0.01*(drx[34] - drx[74])]))\n",
+    "outer_1_y = np.concatenate((dry[34:45], dry[63:75],[dry[34] + 0.01*(dry[34] - dry[74])]))\n",
+    "outer_2_x = np.concatenate((drx[45:63], [drx[45] + 0.01*(drx[62] - drx[45])]))\n",
+    "outer_2_y = np.concatenate((dry[45:63], [dry[45] + 0.01*(dry[62] - dry[45])]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 103,
+   "metadata": {
+    "scrolled": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(inner_x, inner_y)\n",
+    "for i in range(len(inner_x)):\n",
+    "    ax.text(inner_x[i], inner_y[i], f\"{i}\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Rounding a corner means:\n",
+    "- get the corner vertex c\n",
+    "- get the two vertices v1 and v2 on either side of the corner\n",
+    "- choose a rounding radius r\n",
+    "- calculate the center of a circle of radius r that has c-v1 and c-v2 as tangents\n",
+    "- in parametric representation calculate the parameter for v1 and for v2\n",
+    "- generate arbitrarily many points between v1 and v2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 104,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from numpy import linalg\n",
+    "def circle_m(cc, v1, v2, r):\n",
+    "    c = np.array(cc)\n",
+    "    r1 = np.array(v1) - c\n",
+    "    r2 = np.array(v2) - c\n",
+    "    n1 = np.array([r1[1], -r1[0]]) / linalg.norm(r1)\n",
+    "    n2 = np.array([-r2[1], r2[0]]) / linalg.norm(r2)\n",
+    "    v1pr = np.array(v1) + r * n1\n",
+    "    v2pr = np.array(v2) + r * n2\n",
+    "    Dg = - n1[0]*v1pr[0] - n1[1]*v1pr[1]\n",
+    "    Dh = - n2[0]*v2pr[0] - n2[1]*v2pr[1]\n",
+    "    my = (n2[0] / n1[0] * Dg - Dh) / (n2[1] - n2[0] * n1[1] / n1[0])\n",
+    "    mx = (- n1[1] * my - Dg) / n1[0]\n",
+    "    return np.array([mx, my])\n",
+    "\n",
+    "def circle_points(M, radius, N):\n",
+    "    ts = np.linspace(0, 2.*np.pi, N)\n",
+    "    xs = M[0] + radius * np.cos(ts)\n",
+    "    ys = M[1] + radius * np.sin(ts)\n",
+    "    return xs, ys"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 105,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "radius1 = 0.003\n",
+    "M1 = circle_m([inner_x[37],inner_y[37]], [inner_x[36],inner_y[36]], [inner_x[38],inner_y[38]], radius1)\n",
+    "radius2 = 0.0015\n",
+    "M2 = circle_m([inner_x[0],inner_y[0]], [inner_x[37],inner_y[37]], [inner_x[1],inner_y[1]], radius2)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 106,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "cx1, cy1 = circle_points(M1, radius1, 30)\n",
+    "cx2, cy2 = circle_points(M2, radius2, 30)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 107,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(inner_x, inner_y)\n",
+    "for i in range(len(inner_x)):\n",
+    "    ax.text(inner_x[i], inner_y[i], f\"{i}\")\n",
+    "ax.plot(cx1, cy1)\n",
+    "ax.plot(cx2, cy2)\n",
+    "for i in range(len(cx1)):\n",
+    "    ax.text(cx1[i], cy1[i], f\"{i}\")\n",
+    "for i in range(len(cx2)):\n",
+    "    ax.text(cx2[i], cy2[i], f\"{i}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 108,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5ec3066a0>]"
+      ]
+     },
+     "execution_count": 108,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "plt.close('all')\n",
+    "inner_x_smooth = np.concatenate((inner_x[1:36], cx1[22:29], cx2[28:], cx2[:9]))\n",
+    "inner_y_smooth = np.concatenate((inner_y[1:36], cy1[22:29], cy2[28:], cy2[:9]))\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(inner_x_smooth, inner_y_smooth)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 109,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(outer_1_x, outer_1_y)\n",
+    "for i in range(len(outer_1_x)):\n",
+    "    ax.text(outer_1_x[i], outer_1_y[i], f\"{i}\")\n",
+    "\n",
+    "radius1 = 0.003\n",
+    "M1 = circle_m([outer_1_x[10],outer_1_y[10]], [outer_1_x[9],outer_1_y[9]], [outer_1_x[11],outer_1_y[11]], radius1)\n",
+    "radius2 = 0.0015\n",
+    "M2 = circle_m([outer_1_x[11],outer_1_y[11]], [outer_1_x[10],outer_1_y[10]], [outer_1_x[12],outer_1_y[12]], radius2)\n",
+    "radius3 = 0.0025\n",
+    "M3 = circle_m([outer_1_x[22],outer_1_y[22]], [outer_1_x[21],outer_1_y[21]], [outer_1_x[0],outer_1_y[0]], radius3)\n",
+    "radius4 = 0.002\n",
+    "M4 = circle_m([outer_1_x[0],outer_1_y[0]], [outer_1_x[22],outer_1_y[22]], [outer_1_x[1],outer_1_y[1]], radius4)\n",
+    "\n",
+    "cx1, cy1 = circle_points(M1, radius1, 30)\n",
+    "cx2, cy2 = circle_points(M2, radius2, 30)\n",
+    "cx3, cy3 = circle_points(M3, radius3, 30)\n",
+    "cx4, cy4 = circle_points(M4, radius4, 30)\n",
+    "\n",
+    "\n",
+    "ax.plot(cx1, cy1)\n",
+    "ax.plot(cx2, cy2)\n",
+    "ax.plot(cx3, cy3)\n",
+    "ax.plot(cx4, cy4)\n",
+    "for i in range(len(cx1)):\n",
+    "    ax.text(cx1[i], cy1[i], f\"{i}\")\n",
+    "for i in range(len(cx2)):\n",
+    "    ax.text(cx2[i], cy2[i], f\"{i}\")\n",
+    "for i in range(len(cx3)):\n",
+    "    ax.text(cx3[i], cy3[i], f\"{i}\")\n",
+    "for i in range(len(cx4)):\n",
+    "    ax.text(cx4[i], cy4[i], f\"{i}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 110,
+   "metadata": {
+    "scrolled": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5ed12c790>]"
+      ]
+     },
+     "execution_count": 110,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "outer_1_x_smooth = np.concatenate((outer_1_x[1:10], cx1[21:28], cx2[27:], cx2[:7], outer_1_x[12:22], cx3[8:15], cx4[14:23]))\n",
+    "outer_1_y_smooth = np.concatenate((outer_1_y[1:10], cy1[21:28], cy2[27:], cy2[:7], outer_1_y[12:22], cy3[8:15], cy4[14:23]))\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(outer_1_x_smooth, outer_1_y_smooth)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 111,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(outer_2_x, outer_2_y)\n",
+    "for i in range(len(outer_2_x)):\n",
+    "    ax.text(outer_2_x[i], outer_2_y[i], f\"{i}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 112,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbAAAAEgCAYAAADVKCZpAAAK20lEQVR4Xu3VgQkAAAgCwdx/6eZ4uCaQM3DnCBAgQIBAUGDBzCITIECAAIEzYJ6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECDzIbwEhPy/9RgAAAABJRU5ErkJggg==\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(outer_2_x, outer_2_y)\n",
+    "for i in range(len(outer_2_y)):\n",
+    "    ax.text(outer_2_x[i], outer_2_y[i], f\"{i}\")\n",
+    "\n",
+    "radius1 = 0.002\n",
+    "M1 = circle_m([outer_2_x[17],outer_2_y[17]], [outer_2_x[16],outer_2_y[16]], [outer_2_x[0],outer_2_y[0]], radius1)\n",
+    "radius2 = 0.002\n",
+    "M2 = circle_m([outer_2_x[0],outer_2_y[0]], [outer_2_x[17],outer_2_y[17]], [outer_2_x[1],outer_2_y[1]], radius2)\n",
+    "\n",
+    "cx1, cy1 = circle_points(M1, radius1, 30)\n",
+    "cx2, cy2 = circle_points(M2, radius2, 30)\n",
+    "\n",
+    "\n",
+    "ax.plot(cx1, cy1)\n",
+    "ax.plot(cx2, cy2)\n",
+    "for i in range(len(cx1)):\n",
+    "    ax.text(cx1[i], cy1[i], f\"{i}\")\n",
+    "for i in range(len(cx2)):\n",
+    "    ax.text(cx2[i], cy2[i], f\"{i}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 113,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5ed2b0130>]"
+      ]
+     },
+     "execution_count": 113,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "outer_2_x_smooth = np.concatenate((outer_2_x[1:17], cx1[5:14], cx2[13:21]))\n",
+    "outer_2_y_smooth = np.concatenate((outer_2_y[1:17], cy1[5:14], cy2[13:21]))\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(outer_2_x_smooth, outer_2_y_smooth)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 114,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 11.71 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 30.80 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 51.71 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "(<Figure size 432x288 with 1 Axes>, <AxesSubplot:>)"
+      ]
+     },
+     "execution_count": 114,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "filename = \"design_v4rds_inner_smooth.txt\"\n",
+    "hole_to_SC_curves(inner_x_smooth, inner_y_smooth, filename, num_holes=36)\n",
+    "filename = \"design_v4rds_outer_1_smooth.txt\"\n",
+    "hole_to_SC_curves(outer_1_x_smooth, outer_1_y_smooth, filename, num_holes=36)\n",
+    "filename = \"design_v4rds_outer_2_smooth.txt\"\n",
+    "hole_to_SC_curves(outer_2_x_smooth, outer_2_y_smooth, filename, num_holes=36)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Full cutout test, find out how much the drum wants to bend"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 115,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbAAAAEgCAYAAADVKCZpAAAK20lEQVR4Xu3VgQkAAAgCwdx/6eZ4uCaQM3DnCBAgQIBAUGDBzCITIECAAIEzYJ6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECBgwP0CAAAECSQEDlqxNaAIECBAwYH6AAAECBJICBixZm9AECBAgYMD8AAECBAgkBQxYsjahCRAgQMCA+QECBAgQSAoYsGRtQhMgQICAAfMDBAgQIJAUMGDJ2oQmQIAAAQPmBwgQIEAgKWDAkrUJTYAAAQIGzA8QIECAQFLAgCVrE5oAAQIEDJgfIECAAIGkgAFL1iY0AQIECDzIbwEhPy/9RgAAAABJRU5ErkJggg==\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5eae451f0>]"
+      ]
+     },
+     "execution_count": 115,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ts = np.linspace(0., 2.*np.pi*35./36, 36)\n",
+    "xs = []\n",
+    "ys = []\n",
+    "\n",
+    "\n",
+    "r_in = 0.45\n",
+    "r_out = 0.46\n",
+    "for t in ts[-1::-1]:\n",
+    "    xs.append(r_out * np.cos(t))\n",
+    "    ys.append(r_out * np.sin(t))\n",
+    "\n",
+    "xs.append(-0.43)\n",
+    "ys.append(0)\n",
+    "xs.append(-0.43)\n",
+    "ys.append(ys[0])\n",
+    "xs.append(xs[-3]-0.02)\n",
+    "ys.append(ys[0])\n",
+    "\n",
+    "fig, ax = plt.subplots(1,1)\n",
+    "ax.plot(xs,ys, '-')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 116,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "(<Figure size 432x288 with 1 Axes>, <AxesSubplot:>)"
+      ]
+     },
+     "execution_count": 116,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "filename = \"cutout.txt\"\n",
+    "hole_to_SC_curves(xs, ys, filename, num_holes=1)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Standard Design, shorter Arms"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 117,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "drx = copy.deepcopy(filterX)\n",
+    "dry = copy.deepcopy(filterY)\n",
+    "avx = np.mean(drx)\n",
+    "avy = np.mean(dry)\n",
+    "drx = [avx + 0.5 * (x - avx) for x in drx]\n",
+    "dry = [avy + 0.5 * (y - avy) for y in dry]\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.plot(drx,dry)\n",
+    "ax.plot(filterX,filterY, ls='dashed')\n",
+    "ax.set_aspect('equal')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 118,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 11.48 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "(<Figure size 432x288 with 1 Axes>, <AxesSubplot:>)"
+      ]
+     },
+     "execution_count": 118,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "filename = \"shortarms.txt\"\n",
+    "hole_to_SC_curves(drx, dry, filename, num_holes=36)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "This needs more thinking, it doesn't work that easily. Just scaling down doesn't even produce arms anymore."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# V4rds but with stress optimization L1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 119,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "plt.close('all')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 120,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5ea6483d0>]"
+      ]
+     },
+     "execution_count": 120,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "import copy\n",
+    "drx = copy.deepcopy(filterX)\n",
+    "dry = copy.deepcopy(filterY)\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(drx, dry)\n",
+    "for i in range(len(drx)):\n",
+    "    ax.text(drx[i], dry[i], f\"{i}\")\n",
+    "\n",
+    "x0 = []\n",
+    "y0 = []\n",
+    "for i in range(len(drx)):\n",
+    "    x0n, y0n = rot([drx[i],dry[i]],-10)\n",
+    "    x0.append(x0n)\n",
+    "    y0.append(y0n)\n",
+    "for i in range(len(x0)):\n",
+    "    ax.text(x0[i], y0[i], f\"{i}\")\n",
+    "ax.plot(x0,y0)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 121,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.legend.Legend at 0x1b5ed2d0670>"
+      ]
+     },
+     "execution_count": 121,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "#inner stays the same\n",
+    "inner_x = np.concatenate((drx[76:],drx[:33],[drx[76]+0.01*(drx[32] - drx[76])]))\n",
+    "inner_y = np.concatenate((dry[76:],dry[:33],[dry[76]+0.01*(dry[32] - dry[76])]))\n",
+    "#outer is now two holes\n",
+    "#bridge is 58,59 to 44,45\n",
+    "outer_1_x = np.concatenate((drx[34:45], drx[59:75],[drx[34] + 0.01*(drx[34] - drx[74])]))\n",
+    "outer_1_y = np.concatenate((dry[34:45], dry[59:75],[dry[34] + 0.01*(dry[34] - dry[74])]))\n",
+    "outer_2_x = np.concatenate((drx[45:59], [drx[45] + 0.01*(drx[58] - drx[45])]))\n",
+    "outer_2_y = np.concatenate((dry[45:59], [dry[45] + 0.01*(dry[58] - dry[45])]))\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.plot(inner_x,inner_y,label='inner')\n",
+    "ax.plot(outer_1_x,outer_1_y,label='outer 1')\n",
+    "ax.plot(outer_2_x,outer_2_y,label='outer 2')\n",
+    "ax.set_aspect('equal')\n",
+    "plt.legend()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Smoothen inner"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 122,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(inner_x, inner_y)\n",
+    "for i in range(len(inner_x)):\n",
+    "    ax.text(inner_x[i], inner_y[i], f\"{i}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 123,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "radius1 = 0.003\n",
+    "M1 = circle_m([inner_x[37],inner_y[37]], [inner_x[36],inner_y[36]], [inner_x[38],inner_y[38]], radius1)\n",
+    "radius2 = 0.0015\n",
+    "M2 = circle_m([inner_x[0],inner_y[0]], [inner_x[37],inner_y[37]], [inner_x[1],inner_y[1]], radius2)\n",
+    "\n",
+    "cx1, cy1 = circle_points(M1, radius1, 30)\n",
+    "cx2, cy2 = circle_points(M2, radius2, 30)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 124,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(inner_x, inner_y)\n",
+    "for i in range(len(inner_x)):\n",
+    "    ax.text(inner_x[i], inner_y[i], f\"{i}\")\n",
+    "ax.plot(cx1, cy1)\n",
+    "ax.plot(cx2, cy2)\n",
+    "for i in range(len(cx1)):\n",
+    "    ax.text(cx1[i], cy1[i], f\"{i}\")\n",
+    "for i in range(len(cx2)):\n",
+    "    ax.text(cx2[i], cy2[i], f\"{i}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 125,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbAAAAEgCAYAAADVKCZpAAAgAElEQVR4Xu2dCZQeVZmGb0jobJ21sweaAAnZCBASCMgiGJgA4zAojAoHRx0ZxwVncERGRB3E9QgunOPoqAyijIqOiIIgKEsIRiBkBRKykJCQfV86a6c7me+tvyr503R3uv+qv7vq1nPP+U7tVfc+36166966dW8HR4AABCAAAQhkkECHDMaZKEMAAhCAAAQcAkYmgAAEIACBTBJAwDLpNiINAQhAAAIIGHkAAhCAAAQySQABy6TbiDQEIAABCCBg5AEIQAACEMgkAQQsk24j0hCAAAQggICRByAAAQhAIJMEELBMuo1IQwACEIAAAkYegAAEIACBTBJAwDLpNiINAQhAAAIIGHkAAhCAAAQySQABy6TbiDQEIAABCCBg5AEIQAACEMgkAQQsk24j0hCAAAQggICRByAAAQhAIJMEELBMuo1IQwACEIAAAkYegAAEIACBTBJAwDLpNiINAQhAAAIIGHkAAhCAAAQySQABy6TbiDQEIAABCCBg5AEIQAACEMgkAQQsk24j0hCAAAQggICRByAAAQhAIJMEELBMuo1IQwACEIAAAkYegAAEIACBTBJAwDLpNiINAQhAAAIIGHkAAhCAAAQySQABy6TbiDQEIAABCCBg5AEIQAACEMgkAQQsk24j0hCAAAQggICRByAAAQhAIJMEELBMuo1IQwACEIAAAkYegAAEIACBTBJAwDLpNiINAQhAAAIIGHkAAhCAAAQySQABy6TbiDQEIAABCCBg5AEIQAACEMgkAQQsk24j0hCAAAQggICRByAAAQhAIJMEELBMuo1IQwACEIAAAkYegAAEIACBTBJAwDLpNiINAQhAAAIIGHkAAhCAAAQySQABy6TbiDQEIAABCCBg5AEIQAACEMgkAQQsk24j0hCAAAQggICRByAAAQhAIJMEELBMuo1IQwACEIAAAkYegAAEIACBTBJAwDLpNiINAQhAAAIIGHkAAhCAAAQySQABy6TbiDQEIAABCCBg5AEIQAACEMgkAQQsk24j0hCAAAQggICRByAAAQhAIJMEELBMuo1IQwACEIAAAkYegAAEIACBTBJAwDLpNiINAQhAAAIIGHkAAhCAAAQySQABy6TbiDQEIAABCCBg5AEIQAACEMgkAQQsk24j0hCAAAQggICRByAAAQhAIJMEELBMuo1IQwACEIAAAkYegAAEIACBTBJAwDLpNiINAQhAAAIIGHkAAhCAAAQySQABy6TbiDQEIAABCCBg5AEIQAACEMgkAQQsk24j0hCAAAQggICRByAAAQhAIJMEELBMuo1IQwACEIAAAkYegAAEIACBTBJAwDLpNiINAQhAAAIIGHkAAhCAAAQySQABy6TbiDQEIAABCCBg5AEIQAACEMgkAQQsk24j0hCAAAQggICRByAAAQhAIJMEELBMuo1IQwACEIAAAkYegAAEIACBTBJAwDLpNiINAQhAAAIIGHkAAhCAAAQySQABy6TbiDQEIAABCCBg5AEIQAACEMgkAQQsk24j0hCAAAQggICRByAAAQhAIJMEELBMuo1IQwACEIAAAkYegAAEIACBTBJAwDLpNiINAQhAAAIIGHkAAhCAAAQySQABy6TbiDQEIAABCCBg5AEIQAACEMgkAQQsk24j0hCAAAQggICRByAAAQhAIJMEELBMuo1IQwACEIAAAkYegAAEIACBTBJAwDLpNiINAQhAAAIIGHkAAhCAAAQySQABy6TbiDQEIAABCCBg5AEIQAACEMgkAQQsk24j0hCAAAQggICRByAAAQhAIJMEvBWwqqqqg8OGDcukU4g0BCAAgfYiMGvWrE127f7tdf3WXNdbAZswYcLBmTNntoYF+0IAAhDIPYEOHTrMMggTswACAcuCl4gjBCAAgTYigIC1EejmLkMJLAVOIAoQgMARBPbXH3C7a+vd3v31bo9N99i04XIHK1a887QhzZL75Yw33V1PLHK1dQdcdVU3N2XsIPeP557generiE0cAYuNMP4JELD4DDkDBHwkcPDgQbe//qCrNTGRAES2r67e7bPlYLpf03Be02A52l60rXg/m5cwSZAkTIFIRQIVrqs7cPCoSPtVVriZn7+02f3++vom9+gra92xHY9xC9bucDPe2OIG9OjsfnD9BDfhhD5HvUZzOyBgsfAlczAClgxHzgKBuAQkGHpwHxKLUDgiQXjr+iJRKdq3WGwkPhKVSIQkNoX5+sJ13iJOhXPus/UqBVmUYofOnY5xgR3bMZhWmHWr6Oi62nIXM02DZbPi5WA+3E/bo21aV9i/kxvau2ur4vfq6u3uxl/Mdpt31rpHPnm+G9ave6uOL94ZASsZXXIHImDJseRM6SZw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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5ed8c7df0>]"
+      ]
+     },
+     "execution_count": 125,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "plt.close('all')\n",
+    "inner_x_smooth = np.concatenate((inner_x[1:36], cx1[22:29], cx2[28:], cx2[:9]))\n",
+    "inner_y_smooth = np.concatenate((inner_y[1:36], cy1[22:29], cy2[28:], cy2[:9]))\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(inner_x_smooth, inner_y_smooth)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Smoothen outer 1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 126,
+   "metadata": {
+    "scrolled": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbAAAAEgCAYAAADVKCZpAAAgAElEQVR4Xu2dB3xUVfbHjxB6QiAhhE5oUi0giCgIiBSR4gqKhSZi7wXBP+qCrgu4irIoFlRclF0Li6iggIKIIk2a9F5CS+hJCB3+53eTyYZhkszMezO8F3738znMMHnvvjPf+2Z+c+8999xLhIUESIAESIAEXEjgEhf6TJdJgARIgARIQChgvAlIgARIgARcSYAC5spmo9MkQAIkQAIUMN4DJEACJEACriRAAXNls9FpEiABEiABChjvARIgARIgAVcSoIC5stnoNAmQAAmQAAWM9wAJkAAJkIArCVDAXNlsdJoESIAESIACxnuABEiABEjAlQQoYK5sNjpNAiRAAiRAAeM9QAIkQAIk4EoCFDBXNhudJgESIAESoIDxHiABEiABEnAlAQqYK5uNTpMACZAACVDAeA+QAAmQAAm4kgAFzJXNRqdJgARIgAQoYLwHSIAESIAEXEmAAubKZqPTJEACJEACFDDeAyRAAiRAAq4kQAFzZbPRaRIgARIgAQoY7wESIAESIAFXEqCAubLZ6DQJkAAJkAAFjPcACZAACZCAKwlQwFzZbHSaBEiABEiAAsZ7gARIgARIwJUEKGCubDY6TQIkQAIkQAHjPUACJEACJOBKAhQwVzYbnSYBEiABEqCA8R4gARIgARJwJQEKmCubjU6TAAmQAAlQwHgPkAAJkAAJuJIABcyVzUanSYAESIAEKGC8B0iABEiABFxJgALmymaj0yRAAiRAAhQw3gMkQAIkQAKuJEABc2Wz0WkSIAESIAEKGO8BEiABEiABVxKggLmy2eg0CZAACZAABYz3AAmQAAmQgCsJUMBc2Wx0mgRIgARIgALGe4AESIAESMCVBChgrmw2Ok0CJEACJEAB4z1AAiRAAiTgSgIUMFc2G50mARIgARKggPEeIAESIAEScCUBCpgrm41OkwAJkAAJUMB4D5AACZAACbiSAAXMlc1Gp0mABEiABChgvAdIgARIgARcSYAC5spmo9MkQAIkQAIUMN4DJEACJEACriRAAXNls9FpEiABEiABChjvARIgARIgAVcSoIC5stnoNAmQAAmQAAWM9wAJkAAJkIArCVDAXNlsdJoESIAESIACxnuABEiABEjAlQQoYK5sNjpNAiRAAiRAAeM9QAIkQAIk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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(outer_1_x, outer_1_y)\n",
+    "for i in range(len(outer_1_x)):\n",
+    "    ax.text(outer_1_x[i], outer_1_y[i], f\"{i}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 127,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "radius1 = 0.005\n",
+    "radius2 = 0.0025\n",
+    "radius3 = 0.002\n",
+    "radius4 = 0.002\n",
+    "M1 = circle_m([outer_1_x[10],outer_1_y[10]], [outer_1_x[9],outer_1_y[9]], [outer_1_x[11],outer_1_y[11]], radius1)\n",
+    "M2 = circle_m([outer_1_x[11],outer_1_y[11]], [outer_1_x[10],outer_1_y[10]], [outer_1_x[12],outer_1_y[12]], radius2)\n",
+    "M3 = circle_m([outer_1_x[26],outer_1_y[26]], [outer_1_x[25],outer_1_y[25]], [outer_1_x[0],outer_1_y[0]], radius3)\n",
+    "M4 = circle_m([outer_1_x[0],outer_1_y[0]], [outer_1_x[26],outer_1_y[26]], [outer_1_x[1],outer_1_y[1]], radius4)\n",
+    "\n",
+    "cx1, cy1 = circle_points(M1, radius1, 30)\n",
+    "cx2, cy2 = circle_points(M2, radius2, 30)\n",
+    "cx3, cy3 = circle_points(M3, radius3, 30)\n",
+    "cx4, cy4 = circle_points(M4, radius4, 30)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 128,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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rXiYsqI40rfM3/+lfvA/rbhur/lCAbvyFMhN5uiZunvGmxhuuou1Itmms56QHOkfJs5Pa43XWlzr31qRLNTmWefoBeFI3zJ+dx/9wxkjMEf6B15wiIADTEmtq7V20gqPSauKI/2Do8AGrTC/4kl9hlZEY7HKROxI32x8YI2Ac8TvVgHL0I4j/cPIq79WeArinog5WFy/V02am4vf4EjfcFyLacV1C69nCBi8nWHOvuYLBSzrUyCnzNENdDe4o+Omhie141rxZIn5G9w4tmdoto++x7yJlSWv/YMdHbZzuFjbbP1WRxLJa98y8gEzZwgYviOv/YOn2sdaMULEfB1ucDDZWV3y2j/0w3Z8cWzhAYuRDubErCqO9C1EO7FKK+ZgrZwTzvjb8to/iARG+/BCxLUBAXveKmhp7eS1b3DgwIMJCjwPn9Bq9f3E4p/quuYoYK5jzW8iARIgARKwkAAFzEKYbIoESIAESMB1BChgrmPNbyIBEiABErCQAAXMQphsigRIgARIwHUEKGCuY81vIgESIAESsJAABcxCmGyKBEiABEjAdQQoYK5jzW8iARIgARKwkAAFzEKYbIoESIAESMB1BChgrmPNbyIBEiABErCQAAXMQphsigRIgARIwHUEKGCuY81vIgESIAESsJAABcxCmGyKBEiABEjAdQQoYK5jzW8iARIgARKwkAAFzEKYbIoESIAESMB1BChgrmPNbyIBEiABErCQAAXMQphsigRIgARIwHUEKGCuY81vIgESIAESsJAABcxCmGyKBEiABEjAdQQoYK5jzW8iARIgARKwkAAFzEKYbIoESIAESMB1BChgrmPNbyIBEiABErCQAAXMQphsigRIgARIwHUEKGCuY81vIgESIAESsJAABcxCmGyKBEiABEjAdQQoYK5jzW8iARIgARKwkAAFzEKYbIoESIAESMB1BChgrmPNbyIBEiABErCQAAXMQphsigRIgARIwHUEKGCuY81vIgESIAESsJAABcxCmGyKBEiABEjAdQQoYK5jzW8iARIgARKwkAAFzEKYbIoESIAESMB1BChgrmPNbyIBEiABErCQAAXMQphsigRIgARIwHUEKGCuY81vIgESIAESsJAABcxCmGyKBEiABEjAdQQoYK5jzW8iARIgARKwkAAFzEKYbIoESIAESMB1BChgrmPNbyIBEiABErCQAAXMQphsigRIgARIwHUEKGCuY81vIgESIAESsJAABcxCmGyKBEiABEjAdQQoYK5jzW8iARIgARKwkAAFzEKYbIoESIAESMB1BChgrmPNbyIBEiABErCQAAXMQphsigRIgARIwHUEKGCuY81vIgESIAESsJAABcxCmGyKBEiABEjAdQQoYK5jzW8iARIgARKwkAAFzEKYbIoESIAESMB1BChgrmPNbyIBEiABErCQAAXMQphsigRIgARIwHUEKGCuY81vIgESIAESsJAABcxCmGyKBEiABEjAdQQoYK5jzW8iARIgARKwkAAFzEKYbIoESIAESMB1BChgrmPNbyIBEiABErCQAAXMQphsigRIgARIwHUEKGCuY81vIgESIAESsJAABcxCmGyKBEiABEjAdQQoYK5jzW8iARIgARKwkAAFzEKYbIoESIAESMB1BChgrmPNbyIBEiABErCQAAXMQphsigRIgARIwHUEKGCuY81vIgESIAESsJAABcxCmGyKBEiABEjAdQQoYK5jzW8iARIgARKwkAAFzEKYbIoESIAESMB1BChgrmPNbyIBEiABErCQAAXMQphsigRIgARIwHUEKGCuY81vIgESIAESsJAABcxCmGyKBEiABEjAdQQoYK5jzW8iARIgARKwkAAFzEKYbIoESIAESMB1BChgrmPNbyIBEiABErCQAAXMQphsigRIgARIwHUEKGCuY81vIgESIAESsJAABcxCmGyKBEiABEjAdQQoYK5jzW8iARIgARKwkAAFzEKYbIoESIAESMB1BP4fpQf/PaY5clQAAAAASUVORK5CYII=\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(outer_1_x, outer_1_y)\n",
+    "for i in range(len(outer_1_x)):\n",
+    "    ax.text(outer_1_x[i], outer_1_y[i], f\"{i}\")\n",
+    "ax.plot(cx1, cy1)\n",
+    "ax.plot(cx2, cy2)\n",
+    "ax.plot(cx3, cy3)\n",
+    "ax.plot(cx4, cy4)\n",
+    "for i in range(len(cx1)):\n",
+    "    ax.text(cx1[i], cy1[i], f\"{i}\")\n",
+    "for i in range(len(cx2)):\n",
+    "    ax.text(cx2[i], cy2[i], f\"{i}\")\n",
+    "for i in range(len(cx3)):\n",
+    "    ax.text(cx3[i], cy3[i], f\"{i}\")\n",
+    "for i in range(len(cx4)):\n",
+    "    ax.text(cx4[i], cy4[i], f\"{i}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 129,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbAAAAEgCAYAAADVKCZpAAAgAElEQVR4Xu2dB3gUVffGD7333kLvTQhVBVGq2AX1L4KgH/Ze8FNERQTh089eUQSkWFFRpCgCEZTeS+gllNASWighofzfM2z8YkxCsjOze2f3vTzn2STM3Dnzu3f33Xvn3HNzCAsJkAAJkAAJeJBADg/6TJdJgARIgARIQChg7AQkQAIkQAKeJEAB82Sz0WkSIAESIAEKGPsACZAACZCAJwlQwDzZbHSaBEiABEiAAsY+QAIkQAIk4EkCFDBPNhudJgESIAESoICxD5AACZAACXiSAAXMk81Gp0mABEiABChg7AMkQAIkQAKeJEAB82Sz0WkSIAESIAEKGPsACZAACZCAJwlQwDzZbHSaBEiABEiAAsY+QAIkQAIk4EkCFDBPNhudJgESIAESoICxD5AACZAACXiSAAXMk81Gp0mABEiABChg7AMkQAIkQAKeJEAB82Sz0WkSIAESIAEKGPsACZAACZCAJwlQwDzZbHSaBEiABEiAAsY+QAIkQAIk4EkCFDBPNhudJgESIAESoICxD5AACZAACXiSAAXMk81Gp0mABEiABChg7AMkQAIkQAKeJEAB82Sz0WkSIAESIAEKGPsACZAACZCAJwlQwDzZbHSaBEiABEiAAsY+QAIkQAIk4EkCFDBPNhudJgESIAESoICxD5AACZAACXiSAAXMk81Gp0mABEiABChg7AMkQAIkQAKeJBCyAlaqVKnz1apV82Sj0GkSIAESCBaBZcuWxeHaZYJ1/excN2QFLDIy8vzSpUuzw4LHkgAJkEDYE8iRI8cyQGjhBRAUMC+0En0kARIggQARoIAFCHRml+EIzIBGoAskQAKeI0ABM6DJKGAGNAJdIAES8BwBCpgBTUYBM6AR6AIJkIDnCFDADGgyCpgBjUAXSIAEPEeAAmZAk1HADGgEukACJOA5AhQwA5qMAmZAI9CFixI4f/68JJ89L6eSz8ppWGLyOevnRJ/pz1oqlygAKyj58+S6aJ08gATsEKCA2aHn0LkUMIdAsppMCZw4fUY27EuQ9XuPyb6jiZbwXBCgc5J4Bq9JMH1VYfL9fFr/76/jzsq581mHXKZIPqkCMYsoWVCqqEHUrNeSBaRCsQKSK2fIrozJOiQeaYsABcwWPmdOpoA5w5G1XCCgI6VYCFR07DFLrFIs5tBJ/N+FY1Q7CmCEpKOkC5bzr58v/D2n5NPX3LmkQF78H171uAJ5c0m+3BeO/d/5Oa2f9Xi99u7Dp2QXrrXr8EnZqa+HTsneo6f+Jn654UAliNsFUbswYvuf0BWQkoXyCj6c2KQkkCkBCpgBHYQCZkAjeNQFHR1tOXDcEqvoVGJ1LPHMX3dUrVRBqV+haCorIpWKFwioQCSfPSd7jyReEDQImwrchZ9PyW68xp9I+lsLFIJQ6mgtRdjqVygiHeuXs4SNhQRSCFDADOgLFDADGsEDLhxMOP03kdKR1daDJ+Ssb15PR0H18EGfIlYN8HPd8kWlcL7cxt+dTm9eELZTvlHbSYzk/jeC06lOHTW2rFZSujYsL10alrPEjSW8CVDADGh/CpgBjWCYC/uPJcrCbfGpRlYJEnf89F9eViyW/x+jqqqlCoXkcyWdllyHEeav6/bJL+v2y8b9CRaHhhWLWmKmVqdc4YCOKA3rLmHrDgXMgKangBnQCEF24WTSGVm0/ZD8sTlO5m0+KJv2H7c8ypsrp9TGh/P/pgCLSANMBxYvGL5TaTviTkDI9smv0ftl+c7D1nO9qpgmvSBm5aRZlRKSkwEiQe7Rgbk8BSwwnDO9CgXMgEYIsAvnMO2no4q5ECsVrWUxhyUJz4nyIkCiFabJLq9dWi6vVRpTgEUkD0SMJX0CBxIS5bfoA5agzd8aZ4X5ly6cTzo3KGeJ2aU1S1tMWUKTAAXMgHalgBnQCAFwYc+RUxCrgxCtOJm/JU4On0y2rqqjq3Y+wWpVvSTXT/nZFscSkyVq40FLzKI2HJATWApQBM//OtQra4lZh7plPfE80M/bD8vTKGAGNDsFzIBGcMGFBHygLtym04IHZR4EaxsCLrSUxfqodrXLWKJ1GUZZul6KxVkCGp2pI7Jf8cxsJqYaNcpRp2Mvq1XKmmrshBGajtRYvE2AAmZA+1HADGgEB1w4gynA1XuOyrxNcfLHloOyYucROYOpQo0ObF0D04IQq/Z1ykjtsgw4cAB3lqvQKE2dorWCQKL3WZGOusTsMkwvPnJVLbRNqSzXxQPNIkABM6A9KGAGNIKfLsTEn0DQBQQL9ie+8Sdg/ZV+ODauVMwSLH2WFVm1BBb/Mq2Sn4gdPU0jGtfvTbCmGb9cvFMOYGmCttMTnetY7cTiLQIUMAPaiwJmQCNkw4UtBxJkyqq98vPqWGsdlhZdGGw9x9JpQXyzL8EFt9kgGpxDdZpxwsIY+fj3rViikCRXYHSsQnZJleLBcYhXzTYBCli2kTl/AgXMeaZO16gjrZ9X74VwxVr5BHWU1aZ6KenWqLwlXNVLF+I6JKehB6g+XcIwbkGMjISQaWBNp/pl5fFOdaQRRtEsZhOggBnQPhQwAxohHRc0anAqRlk62lqDZ1taWmCa6domFaR74wpStmh+Mx2nV34ROI5sIGP/3C6fzN0mmopLIxd1RFYP2UxYzCRAATOgXShgBjSCz4UDyIAxdc2FkdZyBGFoaVq5GESrolwD4aqIqUKW0Cag4fij/9gun83bLgkQNW33xzvWxoLyIqF94x68OwqYAY1GAQtuI8QjRdP0tfss0Vq845CV2UHXZulIS01TNLGEH4EjJ5NkFERsDEZlJ/G87PqmFeUxCFmNMoXDD4ahd0wBM6BhKGCBb4SjeNahkWhTMEU4f2u8lRC3ZplCch0+pHS0VQuh7iwkoAQOYQ3ZyLlbZdz8GDmN/dJualZZHu1Yi19sDOge4S5g3dAG78A0xnkUbEQGbdIDf58EawlbCrsDNiDVsU3wc3PYSlgkbCxM55qmwR6DZboNIAUsMO8EXVj82/r91jMtzTeoaYc0h96FkVZFPOsowkCMwDSFJ6+iuwFoxKJGLur6vlsiK8vDWEfGrPjBa85wFjAVrU2wzrDdsCWw22HRaZpDJ76nwjR76sM+AUt9SGP8MhlW0/fHxXh9FLbIJ2Dv4nV6Zk1MAXPvDaARZrORVkinB+cgzVDSmXNWyLs+17gOotWoUlGKlnv4Q7Jm3Sngo6it8sWinfhmel5ua1lFHrqylrXLNEtgCYSzgLUF6sGwrj7kz/leh6dpgrfx+0yYjrieTkfAXsXfdIT1PKwCbA6snq8OFcQOsPsoYIHr2DoduADTgt8t3y0z8GxL95LS9E0aOahThM2wzofZygPXHqF6pVhEqX4wZ4t8s3SX5MC/Xq0j5KkudaRI/jyhesvG3Vc4C1hPtIZOIfb3tUofvLaG6Sgrpei0oAqTTiFGZSBgW/H3G2BrYS1gOg3ZyVdBO7z+G3YtBcz9vr/t4HFLtH5YvkdijyZK0fy5MdKqKDdcUtHaCDEXt9hwvxHC8Aq6u/T7s7fIt8t2WVGqb912idXfWNwnQAHLWMB0D4bZsH6wHRkImAqePjvTaUQt2RGwe3G8mkRERETGxMS439oheIWjp5KtjBjfLdtthb2rRmlGhR54PtEJW9DnRx5CFhIIBIGliGB94puVsufwKXmgQ01ELNbhVi4ugw9nAbvYFKIuw9fR1YWdBUXKww7BrodpIIeWt2AHYTqNqIVTiC53WK1ek+ZqdncVLd3UUJ9r6Y68PSFaN15SiQuMA9AGvET6BHQx9JAp6zCtuNt6vvr2bc0Y0epiZwlnAcsNrhrE0RG2B6ZBHL1g6zLgHYW/p34GpiO0XTCdJtyW6py0QRzv4f80GjHDwiCOrPXwjUjhZE0RrtgjGhFWomAeTA9Wkh7NKzMYI2sIeVSACOiz1+e+X209fx3Yvb70aVOVwUIusA9nAVOc3WEapKHzTKNhw2BDYDrC+ikN77QC1gH/r8+72qQ5TqcRx8I0JEmjDx+BMYzez857GGtwfkIE4SSMtjSdU27MEV6JDQpVtK7CK3fb9RMsT3OdgGZ1GTBptfy+6aA1rf16zyacHXCYergLmMM4/auOI7C/c0vGFKHurDsJD8U1BF7XazVAZgydIrweARnciNC/fsazAk9At2/RdWNDp66XgnlzyfCbm1gJoFmcIUABc4ajrVooYBfwrYs9ao20floZa+2gW7pw3r+mCBtUZEJVW52MJweVwJYDx+WJr1daswi6APql6xtK4Xz6FIPFDgEKmB16Dp0bzgKmz7J+XLnHEi7dpkS3fe+I7Sx0ivCKumUkD35nIYFQIKDBRu/O2iwfRm2xsne8dVtTbKLJcHs7bUsBs0PPoXPDTcBOJZ2VmUjp9AMCMuZiJ2NdeKwZ3zX0XbNjcDNIhzoWqzGSQOpw+wc71JLHOtXmFzU/W4oC5ic4J08LBwE7B5FauC1evkcEoUZoabhxhWL5rWdaPTHa4lYVTvYo1mU6Ac3LOWRKNBY/75Ym+PKmi59rMst9tpuNApZtZM6fEMoCpqHvGvau04R7kR1D5/2vxkPsm5pVktY1SjE7hvPdiTV6iMCMtXsRbr/GCrd/HuH2vRlun63Wo4BlC5c7B4eagGn4sIa+f4+UTtF7j1ki1b52abkJI63OyI5RANFYLCRAAhcIpA6374Dnvq9puH0R7vadlf5BAcsKJZePCQUB06zvur/WDyti5Q9sVYIZQ2tqREdamkCXoe8udyJW72kCGm4/HuH2wxBuXwizFMNvbixdGzLc/mKNSgG7GKEA/L9XBUyDL+ZvjbOS586AeJ1EcIZuVaKidSOMm0IGoPPwEiFFQMPtH/96hazdc0zua19D/t2tHndOyKSFKWAGdH+vCVh07DGMtHbjuVasHEAYfBHN+o6tSlS4NAs3tyoxoFPRBc8S0HD7V36OtkZk+r5649amTEqdQWtSwAzo5l4QsH0IwNBADA3I0PVamtKpQ92ycnPzSlZKJ2Z9N6Aj0YWQIaBTiqPmbZdh09ZjrVgJ+fTOFlKykO6py5KaAAXMgP5gqoDpzrOaykm3K5mPDSLxnpJmEcWtkda1WK/FN5QBnYcuhDSBaWv2YkpxpTU1P6ZfS6lWulBI3292b44Cll1iLhxvioDpWq21SOc0a/0BmbVhvzUPryWiZEHrmZYKV3W+gVzoAaySBDImsCzmkPT//MIOTqP6tmD2jlSoKGAGvHOCKWAnsKD4D+ytNRuiNXvjAWubEt0UsnlECbkKKZ061itn7bWFjmIAKbpAAuFJYHvcCblrzGJrp/G3sei5O56NsYh+Li0DB90BxPgSsp+ggRYw3QJ9DsRKR1oLkB1DHxoXQehue6xB6YjnWfpsi9ODxr8f6GCYETiEBNf3jFuKnccPy8Cr60v/dtXD/oslBcyAN4HbAqbh7ivQ6WfheZaOtDbuT7DuulqpgkicW85KnqvRg0yca0BnoAskkAmBRGTseOqbVTIVz8bubFtVXrquYVhns6GAGfB2cUvAdE3JR1FbEYixXw6fTLY6eisIlQqWRg7WYO41A1qfLpBA9gjos+r/zNggI+duk054L797ezPsNRaeW7NQwLLXd1w52mkB0w7++q8b5VN0cA1v79ygnCVY7bErbLECeVy5B1ZKAiQQWALjF+yQl35aJw0rFpPP+rUIy/RTFLDA9rl0r+a0gA2bGi2fYg2J7mD87NX1mMbJgDamCyTgBoFZ2Jbo4S9WWM+sx97VMux2daCAudGrslmnkwI2cVGMPP/DWmt+/GXs+srowWw2Bg8nAY8RWLP7qNz9+RLR52Mj+0TKpTVLe+wO/HeXAuY/O8fOdErADiNK6YrX50hjJNEdd3frsH6461jjsCIS8ACB3YdPIsx+ieyIP2Fls7+pWWUPeG3fRQqYfYa2a3BKwAZjPnwc5sWnP9Ze6pYvYtsvVkACJOAdAkdPJcv945dZS2Oe7FxHHrmqVsjPwFDADOifTgjYkZNJ0mrYLOkRWQlbMTQx4K7oAgmQQKAJ6JrOZ79bbe18fmuLyjLspsYhvTyGAhboHpbO9ZwQsAnIXD1o8lr5+ZHLpVGlYgbcFV0gARIIBgFNBPzWb5vl3Vmb5fJapeXD3s2laP7QjD6mgAWjh6W5phMC1uOj+ZKQmCy/PN4+5KcNDGgyukACxhP4ZukuGfj9GqlfoSieibeSEiGYzZ4CZkA3tCtgccdPS4uhv8mArnXloStrGXBHdIEESMAEAprE4P4Jy6UGknBP6N865JbUUMAM6GV2BWxm9H4rR9qk+9tKC2TaYCEBEiCBFAJ/bI6T/uOWWFuyfHFPGylXNH/IwKGAGdCUdgVM08po1o21L3flxpIGtCddIAHTCCxCZOLdY5dI6SL5LBFTMQuFQgEzoBXtCtjtnyyUk0ln5MeHLzfgbugCCZCAiQQ0i33f0YutgI4v7mktVUt5f3NMCpgBPc2ugF02Yra0ql5S3sI+QSwkQAIkkBGBtXuOSu/PFkm+3DmtkVhNjyf0poAZ0NftCJgm7q37wnT51+U1rLyHLCRAAiSQGYEN+45J71GLcEgOmYjADi8nPaCAGdDX7QhYSgTi4OsaSL/LqhtwN3SBBEjAdAK61dIdoxZam9mO/1drz64dpYAZ0NPsCJh+m+r29jz5oFdzuaYJtxk3oDnpAgl4gkAM8ib2+nSRHMP6UV0n1iyihCf8Tu0kBcyAJrMjYCt3HZEbP/hTxvRrKVdizy8WEiABEsgqgT1HTkHEFkpcwmkZc1cr61m6lwoFzIDWsiNgGh57G6IQv8Bc9qVIG8NCAiRAAtkhsP9YoiVisUcSZVTfFnKZhz5Hwl3AuqGh34Hlgo2Cjcig4Xvg75NgLWFLfcdoxtyRsKKwc77/S8RrFEzn8k75juuC1wOZdSg7AjZ300G5E6Gx3z3QViKreuvbU3beZDyWBEjAPQL6LF0DO7bFnZCRvSM9M5sTzgKmorUJ1hm2G7YEdjssOk030X1JpsLywh72CVhuvC6H9YGtgpWCHYGd9QnY077jstTj7AhYShYOJvHNEmoeRAIkkAEB3U9Qvwzrc/X3bm8u3RqVN55VOAtYW7TOYFhXXys953sdnqbV3sbvM2EDYCnC1B0/94L1TqeFo1Idl6UOYEfAfl4da20pPvOJ9mG3nXiW4PIgEiCBLBPQPcXuGrNYVmGXZ11Xen3Tilk+NxgHhrOA9QRwnULs7wOvo6nWMB1lpZTm+OF5mE4hphamx/F7JEyjJsrAvoK95jtJj9MRmY7GvoMNhZ3PrHHtCNh3y3bLU9+ukrkDrpSIUgWD0Yd4TRIggRAicPz0GSvt1NIdh7C7c1PpGWnu7s4UsIwFLCf65GxYP9iONAKmI7GHYPpM7CRsFmyQ77USXvfAdOpRBWwCbFw6/fte/E1NIiIiImNiYvx6C3yxaKcM/GGNLBrYMaSSdPoFgyeRAAk4QuBU0lm5d/xSmYdEwMNuaiR3tK7qSL1OVxLOAnaxKUTdFXIr7LgPuk4IH4JdD9M9S66G9fX93wt41QCO19M0UD/83gKWelT3jza0MwIb++d2GTwlWla80Dkk9/txusOzPhIggawRSEw+Kw9NXC6zNhyQ55Dl5972NYzbazCcBUwDMTSIoyNMR0waxKHPtdZl0LxR+HvKMzBd8aejLs2emwSbAXsL9gusOCwOplugfgn7DfZxZl3GjoCN/H2rDJ++QaKHdJWCefWWWEiABEjAGQKaqePJb1bKz6v3Sr9Lq8kL1zaQXDlzOFO5A7WEs4ApPg3G0CANjUgcDRsGGwLTUPmf0vCNwu+pows1gEMDP/T51jTYMzBN7zwXpuKldap4PQnT52EZFjsCptuGvzlzk2wZdrXkzqWzniwkQAIk4BwBzbc6fPp6+XTedunasJy883/NjNm2KdwFzLlWtlGTHQF7/ZcNMvL3bbLlVdViFhIgARJwh8AYPK4Y8nO0XFKluHzWt6WULKQri4JbKGDB5W9d3Y6ADUWH+nLxTlk3RAMqWUiABEjAPQIz1u6Vx75aKRWxIebYu1oGfU8xCph7bZ3lmu0I2AuT18rUNXtlOYI4WEiABEjAbQLLYg5J/8+XSs4cOeQz5GDVEVmwCgUsWORTXdeOgD0zaZUV6rrgOY1FYSEBEiAB9wlsO3hc+o1ZIgcSEq2sHZ0blHP/oulcgQIWFOx/v6gdAXvsqxWyChnpo7CQmYUESIAEAkVA8yf+Cwue12CX55dvaCR92gR+rRgFLFCtncl17AjYAxOWyVZ8G/r1iSsMuBO6QAIkEE4ETiadkUeQyk7Xij3QoaYM6FJXcgYwzJ4CZkBvsyNgmvLlIPbymfKILkljIQESIIHAEjhz9py89NM6mYisQDdcUhHpp5pIvty6isj9QgFzn/FFr2BHwHRb8NPJ52TSA5de9Do8gARIgATcIHD+/Hn5CEkVXpuxUdrUKCkj+7SQYgV0Oay7hQLmLt8s1W5HwHp+NF/y5ckpE/u3ydK1eBAJkAAJuEXghxW75ZlJq6V66UIIs29lhdu7WShgbtLNYt12BOy69/6QMkXyyWiEs7KQAAmQQLAJzN8SJ/eNXyYF8+WSMf1aSYOKuuevO4UC5g7XbNVqR8C6vPW71CxTWD7CLqosJEACJGACAd0U8y6E2ScknsFnU3NpV1t3nXK+UMCcZ5rtGu0I2BWvz5FmWEj4NvKTsZAACZCAKQT2Hj1lidiWA8dlRI8mruwrRgEzoLXtCFibV2fJFXXKyH8Q+cNCAiRAAiYROJaYLLrU588t8TKwu27JUtNR9yhgjuL0rzI7Atb8lZlyTeMK8sqNjfy7OM8iARIgARcJ6JYsT3y9UqYhj+KX97RBlKJuWO9MoYA5w9FWLXYErOGLM+T2VhEyCPv0sJAACZCAiQROnD4j17w7T1TMpj/e3rEQewqYAa1tR8BqDZwm911RQwZ0rWfAndAFEiABEkifwIqdh6Xnxwvk1hZVZPjNjR3BRAFzBKO9SvwVMF0BX+v56fJk5zryaMfa9pzg2SRAAiTgMoFBk9fIN0t2yx//vlLKFs1v+2oUMNsI7Vfgr4BpHrIGL/4iz11dD6MwZx+O2r8r1kACJEACfyewI+6EXPlGlDyAz6tnutmfNaKAGdDD/BWwwyeSpBmCOAZf10D6XVbdgDuhCyRAAiSQOYELUYkXtoAqlC+3LVwUMFv4nDnZXwHbdzRR2gyfZc0nayAHCwmQAAmYTmDhtnj5v08Wyge9mss1TSrYcpcCZgufMyf7K2Ax8Sfkitej5M1bm8rNzSs74wxrIQESIAEXCeize13+06VhefnvLU1tXYkCZgufMyf7K2Cb9ydI57fmyvu9msm1TSo64wxrIQESIAGXCTz8xXJZuO2QLB7Y0db+YRQwlxsqK9X7K2BrsRPqtUjm++mdLYK2pXdW7o/HkAAJkEBqAt8t2y1PfbtKpjx8uTSuXMxvOBQwv9E5d6K/ArYs5pD0+GiBjLu7lbRHOikWEiABEvACgZTn93YD0ChgBrS2vwKm2xb0GrVIvr63jbR2MD2LAUjoAgmQQAgT0A0wm778q1yPHZyH3uj/omYKmAGdxF8Bm7PhgNw1dolMfugyuQQZ6VlIgARIwCsEbv7wT8mTK6d8fV9bv12mgPmNzrkT/RWwGUiOef+E5TL9sXZSv4J7m8Y5d6esiQRIgAQuEHhm0iqZjS/hSwd19hsJBcxvdM6d6K+A/bhyjzz21UqZ/dQVUgObWrKQAAmQgFcIfDJ3q7w6bYOserGLFCuYxy+3KWB+YXP2JH8F7Jslu+SZ71ZbecUqlyjorFOsjQRIgARcJDAJkYhPIxJx7oArJaKUf59fFDAXGyirVfsrYOMXxsgLk9fKkuc7SZki+bJ6OR5HAiRAAkEnkPIIZNqj7aRBRf8egVDAgt6MIv4K2Kh522To1PWyenAXKZrfvyG4AbdPF0iABMKQwB+b46T3Z4vkGwRxtKpe0i8CFDC/sDl7kr8C9sGcLfL6Lxtl49Buki93LmedYm0kQAIk4CIB3R/spg/ny5h+LeXKemX9uhIFzC9szp7kr4C9OXOTvDtrs2wf3l3QkM46xdpIgARIwEUC62KPYpfmP+Tj3s2lWyP/kvpSwFxsoKxW7a+Avf7LBvn4922yZdjVFLCswuZxJEACRhBYsuOQ3IIdmu1kEqKAGdCU/grY6D+2y5Cfo2X5C52lZKG8BtwJXSABEiCBrBGYsxGJGMYske8fvFSaR5TI2klpjqKA+YXN2ZP8FbBpa/bKgxOXi50oHmfvhLWRAAmQQNYITFkVK498uUJ+faK91ClXJGsnUcD+RqAbfnsHphEQo2AjMqDYA3+fBGsJW+o7pgleR8I0/vOc7/8S8RoJGwsrAJsGewx2PrPW8VfAlsUcRjLf+TK6Xwu5ql45vzoATyIBEiCBYBD4avFOefb7NTL/2aukYnH9uMx+CecRmIrWJpjmMdkNWwK7HRadBqN+NZgK0zm6h2EqYLoP9nJYH9gqWCnYEdhZ2GLYo7BFMBWwd2HTM2safwUs7vhpaTH0NxnYvZ7c275m9lufZ5AACZBAkAi8+etGeR+R1NFDukn+PP5FUYezgGkGycGwrr72e873OjxNe76N32fCBsCe9glYd7z2gvVOc6yG0syB1fP9XQWxA+w+NwRM62z32mxpVLGYfNRbB34sJEACJOANAg9OXCbRscckCpk4/C3hLGA9AU2nEPv74OloqjVMR1kppTl+eB6mU4hRsBQBexw/q2Lo4gXdiOsr2GuwFjCdhuzkq6AdXv8NuzazBvJ3BKZ1PvbVCuxsGi8Ln+vISER/3wU8jwRIIOAEurz1u0SULCSj+urHpn+FApaxgOUE0tmwfrAdaQRMhewhmD4TOwmbBRsEO5oNAbsXx6pJREREZExMjF8tOG7BDnnxx3VM6OsXPZ5EAiQQDAJnzp6T+p6lPtwAACAASURBVC/OkH9dXkOevTplwir7noSzgF1sClH3ud4KO+7DWh6vh2DXw2rBrob19f3fC3jVAI4JsIBOIe49ekouHTFbHr2qtjzRuU72ewDPIAESIIEAE9Cpw+7vzpM3b20qNzev7PfVw1nANBBDgzg6wvbANIhDn2uty4BmFP6eMoWoixZ01HU5LAk2A/YWTIM90gZxvIe/aTBHhsXOFKJWeseohbLr0Cn5fUAHTiP6/VbgiSRAAoEi8FHUVvnPjA2yaGBHKVc0v9+XDWcBU2gajKFBGhoCMxo2DDYEppGGP6WhmlrA9L80gEMDPzREXgXqGd/xOqE7FqZxoRp9+IjvmAwbya6AfYdtCZ7CtgR2cor53YN4IgmQAAlkk8CtIxfI8cQzMg2b8dop4S5gdtg5dq5dAUs6c070gahuz627M+fGKwsJkAAJmEjg6Klkaf7KTLn/ihoyoKv/z7/03ihgBrSwXQHTW/hl3T65b/wyGXRNfenfroYBd0UXSIAESOCfBFI24p10f1tpUc2/bVRSaqWAGdDDnBCw8+fPyz3jlsrsDQeQ3TlSujTUmBMWEiABEjCHgH5OdXlrruTKmcOaLbK7iwYFzIC2dULA9DZOJp2R2z9dJOv3HpNHrqwl97Sv4fcKdwOw0AUSIIEQI5CSwNdu9CFHYAZ1DKcETG/p8IkkGfjDGpm+dh8WCRa0vuUUyqcBl1kvyVij0fGN36V04bxSpkg+vOazXv/2s+9v/qaAybo3PJIESCAUCJw7d15u+2SBFTE995krJW9u+8/qOQIzoGc4KWAptzN/a5wsR7Lfh7E+LLvl+OkzMggieBC5FuMSkqzXQxDG9EoRiOM/Re6C8KX+e6lC+RzpsNm9Fx5PAiRgBoFR87bJ0KnrZcTNjeX/WkU44hQFzBGM9ipxQ8DsefTPs3VUFn88STSB8MEEn6X8bAkd/ub7PQHhsemV4gXzSBnfyK1W2cLSsGJRaVChmNQuV5hTnU43GOsjAYMI6GONG97/U9rXKSOf3hlp+9lXyq1RwAxoZC8IWHYwJSaf/Uvo4iB6/xO8RGtEt+9YomzenyAnkjR5P1L744GuClqDChA0FTVL2IpK8YLcpDM73HksCZhIYHvcCek9apGcxnKfXx5vJ6XwJdapQgFziqSNekJNwLKCQufDdx46KdH4ZrYu9qiVlVp/3n/s9F+nV8IeQSlipq86YtO/2Y1cyop/PIYESMA+AX1v9x29WBB8KJ/f3UoaVdIMfc4VCphzLP2uKRwFLCNYOkWZImbrVNTwBtiGb3D6BtBSNH9uS9QaYguZlBGbjt50ETcLCZCAOQSW7Dgkd49dIvqcfHz/1lKzTGHHnaOAOY40+xVSwDJnpssDNuxL+JuwbcBoTacktOSFeNUpf2EKsnX1UtiduqyUKMTpx+z3RJ5BAs4Q0HD5ByYsk4rFCljipTMnbhQKmBtUs1knBSybwHC4bsewI/4Eph91lHZh+nHtnqNy+GSy4JGatcK/c/1y0rlBOalWulD2L8AzSIAE/CIwZVWsPPH1Sqlbvog1bajLcNwqFDC3yGajXgpYNmBlcqg+V1sDEftt/X6ZGb3fGrVp0SnGTpaYlZVLqpSwsgCwkAAJOE9g4qIYGTR5rbTEF0jdqLJo/jzOXyRVjRQwV/FmrXIKWNY4ZfeoXQgSUTFTW7TtkJyBwOnibJ1iVEFrV7uMFMirGxGwkAAJ2CXwYdQWeW3GRuv99eEdzQOyNIYCZrfVHDifAuYAxItUcRRTi1GbDkDMDkgU8kUmYLF2PmQCaFe7tCVmV9UvK2WL+L8vkft3wCuQgJkENL/hiOkbZOTcbXLDJRXlv7c0DVhQFQXMgD5BAQtsI+j2M4u3H/prqnHPkVMIzRdMLxb3TTWWk9qYdmS4fmDbhVfzHoGzmNUY+P0a+XrpLrmzbVUZfF1DyRnAKXoKmAF9hgIWvEbQb4/r9yb8NdW4evdRy5mqpQpaYqbWsloJ7rEWvCbilQ0lcPrMWStYY9qaffLoVbXkic51Av6ljwJmQOeggBnQCD4X9h1N/EvM5m+JlyREOxYrkMeaGunTpirSXhUxx1l6QgJBIqBLW3T/wXmb44K6ByEFLEgdIPVlKWAGNEI6LmhS43mbDlqZ/WfAVMza1ihlTZVoeD53vjaz3eiVuwT0efJdYxfLyl1HZESPJnJriyruXjCT2ilgQUP/vwtTwAxohIu4EI8MITrPP3HhTtFnZuWL5pderSOQVbsKgz/Mbz566BCBA8hjeidSQ207eELevb2ZdGsU3I1zKWAONaydaihgdugF9lx9aK27Xo9bsMOaPtFExPomvrNtNetZGQM/AtsevFrgCOiylN6fLbKSc396Zwu5rFbpwF08gytRwILeBCIUMAMawQ8XNMv2hIUx8i1GZsewhUw9ZB7og+nFGy+plO1NRP24PE8hgYAR2IikAH0gXjqNPvauVlbErgmFAmZAK1DADGgEGy7oA+2fVsZiVBZjpbTS5KU9IitbYuZGAlMbrvJUEsg2gRU7D0u/MUuwMDmnjP9Xa6ljUCATBSzbzen8CRQw55kGo0YNyV+ON7sK2bQ1eyX57Hm5HNMsKmQdkZ2AQR/BaBVe0w6BPzBNfu/4pdbu6hMgXlVKFrRTnePnUsAcR5r9Cilg2Wdm+hn6nODrJTtl4qKdsheh+RWL5Zc7EIZ/W8sqriY3NZ0L/fMOgRlr98qjX66UGmUKyTgk5S2LwCXTCgXMgBahgBnQCC65oFnzNX3V+IU75E+sK8uTK4d0b1zBCsVvHsGgD5ews1qbBL7Bc91nv1ttPesa06+VFCvoblJef92lgPlLzsHzKGAOwjS4qi0HjltBH98t223lYmyM3WmfRPaCDnXLMHrR4HYLN9dGzdsmQ6eut/KEjuwTKQXz5jYWAQXMgKahgBnQCAF04QTE64cVe+QTJD/didDkyKol5OkudaVtzVIB9IKXIoG/E9BnuG/8uknen7NFrsEswZu3NUXCa7N3a6CAGdCLKWAGNEIQXEjG9KJO1bw3a4vswwJRDfh4qksdaYapRRYSCCQB3UvvpZ/WYao7Rm7H4vyhNzb2xL55FLBA9pIMrkUBM6ARguhCYvJZa2rxo6itEn8iCQmEy0LI6kr9CkWD6BUvHS4E9IvU09+ukh+xFOS+K2rIs93qeWZKmwJmQC+lgBnQCAa4oFOLY/7cbu2rlICF0dc2qWBl+OZaMgMaJ0RdOJV0Vh76YrmVXebfEK4HOtT01J1SwAxoLgqYAY1gkAuaLPWTeVshZjtER2c9mleWxzrVlsolzFqDYxAyuuIHgWOJydJ/7FJZEnNIhmHKUHN7eq1QwAxoMQqYAY1goAtxSCD84ZytMmFRjOgD9l6tIuShK2sZuR7HQHx0KRMC2rf6Iinvpv0J8uatl8h1TSt6khcFzIBmo4AZ0AgGuxCL7Pfvzd5i5VzMjXVkfZE4+P4rakqJQnkN9pqumUpAd1PoM2qRxB49JR/3jsQyjrKmunpRvyhgF0Xk/gEUMPcZh8IVYuJPyNu/bZbJK/dIIazN+dfl1aV/u+pSJL+Zi0xDgXmo3YOuRdSkvLrX3Zh+LaVFtZKevsVwF7BuaL13YLrYYRRsRAat2QN/nwRrCVsKqwZbD9voO34hXu/3/RyF1wqwU77fu+D1QGa9hALm6fdQwJ23pn2wXmfGun1SHBkSdDSmo7ICec1esxNwULzg3wis2X1U+o5ZLDlz5LBSQzWo6P0o13AWMH23b4J1hu2GLYHdDotO0+91D/mpMJ2veTiVgP2Mnxul8x5RAXvad1yW3kIUsCxh4kFpCOgH0n9/3Si/Y9doTbb6MJ6P6Qabpi8+ZUMGnsDCbfHS//OlUqxAHpnQv7VUL10o8E64cMVwFrC24DkY1tXH9Tnf6/A0nN/G7zNhA1IJUzX8TAFzoUOyyuwTWLz9kCVk+lqlZAEZfF1D6Vi/XPYr4hkhSWDW+v3y4MTlViZ5zShfHomlQ6WEs4D1RCPqFGJ/X2P2wWtrmI6yUkpz/PA8TKcQo9II2Dr8riO4Y7BBsHm+k/Q4zQl0FvYdbCjsfGYdhiOwUHk7Be8+NEpxLra+eOXnaNHnHJ0gYC9d18C47S+CRyg8rzwZKcuewiLlRpguHIONKEuGWOAPBSxjAcuJLj8b1g+2I42A5cPvhWHxsEjYZFhDn5hVwusemE49qoBNgI1L5+1zL/6mJhEREZExMTHh+Q7jXTtKIOnMORmNxdDvztosZ5EeSKcV70V2BU4rOorZE5WNW7BDXvxxnbStUUo+7dtCCmOj1VAr4SxgF5tCLIbG3go77mv08ng9BLsepoEcqUsUfknvuVc//L0FLPWo7h99iCOwUHtbBf9+NPR+6NRobKy5T6qVKigv39BIrqhTJviO0QPXCeho/H0su3hj5ibp3KCcvHd7M+ymHJoBPuEsYPp1RKcAO8J0xKRBHL1gOjWYXkktUvpJoGKm04Q1YDp92Bim04nFYXEwjW3+EvYb7OPMei0FzPX3dNheYC4CPDRJ6/a4E3J1o/LywrUNpGLxAmHLI9RvXJPy6lYoOgrXDC7/6dE4pHcCD2cB077cHaZBGvr1ZDRsGGwITEdYP6Xp7KkFTJ+J6XHJsHOwl2BTYBraM9cnXlqniteTMBW6DAsFLNQ/VoJ7f6fPnJVR87ZjMfRmyYF/j3asba0hy5tbZ8lZQoWAbp767PdrZBL2m7vrsmrywjUNJGfOHKFye+neR7gLmBGNSwEzohlC3old2HtMgzx+jd6PBMGF5BVMK16KLVxYvE9Ac2Y++uUKq211k9RHrqrlmYzyduhTwOzQc+hcCphDIFlNlgjM3rBfBv8UbW2mqTnwnu9eP6RCq7MEIYQO0qwa945bKvO3xmMJRQPpd1n1ELq7zG+FAmZAU1PADGiEMHNBv7F//PtW+RB7kOXBNNPjnergg6+a5MnFaUUvdYXD2D+uH7JrrI09Jv+9pYnc1Kyyl9y37SsFzDZC+xVQwOwzZA3+EdD8ioMR5DFn40GpU66wDMG0YhuEXbOYT2Df0UQrr2EMRtIf9mounRBxGG6FAmZAi1PADGiEMHZBw65n4tnJy1OiRTOV39SskjzXvZ6ULRI6GRtCrXl3IKq0N8TrCPaO+/TOFtK2Znh+6aCAGdCzKWAGNAJdEN2d94M5W+QT7AidDxGKT3apI33aVA3pMGwvNvv6vccw8los5/DF43Nk12hcWZeshmehgBnQ7hQwAxqBLvxFYNvB49basXlITVW/QlF5vWcTaVQpfD8kTeoay7B78l1jlkghZNUYj7yGtcpqQqDwLRQwA9qeAmZAI9CFvxHQacXpa/dZQqaBAg8jLFt3g2aQR/A6iu46cN/4pVKhWAGIVyupXKJg8Jwx5MoUMAMaggJmQCPQhXQJHDmZZAV5TF4ZKw2REPaNW5tKvfLe30fKa8398+pYeeLrlVK7bBEZB/EqXVjTsbJQwAzoAxQwAxqBLmRKYAZGY8//sEaOJSZbIff3ta/BZ2MB6jNfLt4pA8G+RdUS8hl2US7KHbj/Ik8BC1AnzOwyFDADGoEuXJRA/PHT8sKPa60EwU2rFJc3sO6oFkYELO4R0LV6I6ZvkA51y8hHd0Ry1+00qClg7vW9LNdMAcsyKh5oAIEpq2ItITuJqMUBXerK3cirmCvEc+4FGrs+g/zPjI3WYnPNlvLGLU2ZuzKdRqCABbpnpnM9CpgBjUAXskXgQEKiDPx+rfyG3X51aut1fMCGyjb12QLhwsG6j9ugyWtFpw57t4mQl69vxC8IGXCmgLnQAbNbJQUsu8R4vAkEdJTwA3b81UjFZM2E3q2e3Nm2WshnQHeTvW5IqsEaU9fstTYjfQpr8fAh7eYlPV03BcyA5qOAGdAIdMFvAprS6NnvV0sU0lG1qVES68aaSpWSDPHOLtCTSWfk/gnLRfdw0wTL9yBQhiVzAhQwA3oIBcyARqALtgjoaOybpbuwXct60Z8HXlNferWK4Oghi1SPIiXU3Z8vkRU7D8uIm5vIrS2rZPHM8D6MAmZA+1PADGgEuuAIgd2HT8q/v1stf26Jl3a1S2NH4CbcAfoiZPV54p1IDbXt4Al55/8ukasbV3CkLcKhEgqYAa1MATOgEeiCYwR0BDZh0U4ZPm295MLzmxewR9UtkZU5GkuHsG4yqhnlDySclpF9IiH6ZRxrh3CoiAJmQCtTwAxoBLrgOIGd8Sfl6UmrZPH2Q9KxXll59ebGUq4oM9yngN68P8HKKJ+YfE7G3NVSmkeUcLwNQr1CCpgBLUwBM6AR6IIrBM4hJHzs/B1Y07RB8ufJJS9hNKbbtYR7ZN3KXUesjSjzYgNRTcpbtzwXhPvTASlg/lBz+BwKmMNAWZ1xBDTD/YBJq2VZzGG5CqOxYTc1spLShmOZvyVO7hm3VEohn+EEiFdEKUZs+tsPKGD+knPwPAqYgzBZlbEEdIGujsZe/2WD5MmZUwZdW19ubVElrEZjv6zbJ498scJa9K0Z5ctyStVWf6WA2cLnzMkUMGc4shZvEIiJPyHPYDS2CM/GLq9VWobj2Vg4rBubtGw37nuVlUdyDJLyFi+Y1xsNZrCXFDADGocCZkAj0IWAEtBnYxORKmkEIhXP48rPXl1PereuGrJZPEb/sV2G/BxtLS34uHektSEli30CFDD7DG3XQAGzjZAVeJSArht77vs11u7PraqXlNewbqwaptdCpeiSgrd+2yzvztosVzcqL29jnVe+3LlC5faCfh8UsKA3gQgFzIBGoAtBI6Af8t8u3S2vTI22cio+jQz3d13m/Qz3Osp8eco6+XxBDJ71VZZXb2rMPdQc7mUUMIeB+lMdBcwfajwn1AhoTkXdNHPWhgNYE1VcXkNOxVplC3vyNlWIB3y7ytrJ+l7kNHwOU6ThvnTAjYakgLlBNZt1UsCyCYyHhywBHY39iA/9wRi56H5jj3eqLfe289buz4nJZ+WhicstIR7Qta482KEmxculHksBcwlsdqqlgGWHFo8NBwKaH/DFyetkBsLOG1cqhv3Gmki98kWNv/WExGTp//lSWbzjkLxyQyPs51XVeJ+97CAFzIDWo4AZ0Ah0wUgCU1fvlRex+/MxCMND2B/rwQ61jN2ZOP74aemL7Bob9ibIm7ddItdjJ2UWdwlQwNzlm6XaKWBZwsSDwpTAoRNJVjCETi3WQ8ol3W+sceViRtGIPXLKymu45/ApK0z+SmQbYXGfAAXMfcYXvQIF7KKIeAAJyMzo/VaQRzwE7T4ERjzasbaVXzHYRdNk9R61SBISz8hnWKCsywFYAkOAAhYYzplehQJmQCPQBU8Q0I0fhyLc/ltktdAIRc3i0bJa8ARj7Z6j0nf0Yovd53e3kkZ4XscSOAIUsMCxzvBKFDADGoEueIrA75sOykAsgN6Dqbue2GtMM3mURnLcQJZF2+KtgI2iBfJYeQ1rlPFmyH8gmTl9LQqY00T9qI8C5gc0nhL2BE4mnZH3Zm+RUfO2SQFMJQ7oVk96tYqQXDlzuM5m9ob98sCE5VK5RAGZ0L912GbWdx30RS5AAQt2C+D6FDADGoEueJbAlgMJ8gJC7hdgRNQEwR1Db2yE1+Ku3c+PK/fIU9+skvoVilrThiULMSmva7ApYJkS6Ib/fQemT4JHwUZkcHQP/H0SrCVsKawabD1so+/4hXi93/dzJF7HwnSzo2mwx2CarzTDQgELVvfndUOFgC6A/mlVLJ6PrZc4hLPrSOyZrvWkWME8jt7i+IUxVlh/Kzx3G9W3hRTJ72z9jjobBpWF8whMRWsTrDNsN2wJ7HZYdJp2161Sp8L0a9bDsBQB+xk/N0qnj+gT3Udhi3wC9i5ep1PAwuDdxFsMOgFdL/bWzE3yOfYdK4HtSvTZWI/mlW1nuVeB/GDOFvnvr5ukU/2y8n6v5kZEQAYdeJAdCGcBawv2g2FdfW3wnO91eJo2eRu/z4QNgD19EQGrgP+fA6vnq0MFsQPsPgpYkHs6Lx9WBNbFHsW04lpZvvOItKhaQl7BtKJO+flTVLxexbYvn87bLjc1q4QcjU0kT66c/lTFcxwmEM4C1hMsdQqxv49pH7y2hukoK6U0xw/Pw3QKMSqNgK3D7zqCOwYbBJsHawHTachOvgra4fXfsGszazdOITrcq1kdCYCAZoPXTSSHT1+PTB5npN+l1azcitmZ9juDpLwDsfbsG2TL1/NfvLaB7dEcG8c5AhSwjAVMv2LNhvWD7UgjYBqvqzGz8TB95jUZ1hBWJxsCdi+OVZOIiIjImJgY51qVNZEACfxF4DAWPr/2y0b5aslOKYNQ+0EQoeuaVLhogl1Nyvv4VyutfIyPYdG0ih8zypvVscJZwC42hagrErfCjvuarDxeD8Guh+lzsNQlCr/o9OIeGKcQzerj9IYELAIrdh6WQZhWXBd7TC6rVUoGdq8vdcoV+dt0oI64NJpxCgJCflm3X46eSrZGXXdfXp0UDSQQzgKme3rrFGBHn/BoEEcvmE4NpldSRErFq4xPzM7itQZMpw8b+/6WNojjPfxdoxEzLJxCNPCdQZdCksBZTCtOXBQjr2NEpqmfcmDJmI7KKhQvgNe8ELkjVqqqwvlyS5cG5aQnNqK8tGbpkGQRCjcVzgKm7dcdpkEaGpE4GjYMNgSmIvVTmgZOLWD6TEyPS4adg70Em+I7Xp+DjYVpGL1GHz4CYxh9KLxbeA8hQ+BgwmnRxcixRxJhp2QvNtPcfyxR6iBZ8HVNKkqHumUYZeiB1g53ATOiiTgCM6IZ6AQJkIDHCFDADGgwCpgBjUAXSIAEPEeAAmZAk1HADGgEukACJOA5AhQwA5qMAmZAI9AFEiABzxGggBnQZBQwAxqBLpAACXiOAAXMgCajgBnQCHSBBEjAcwQoYAY0GQXMgEagCyRAAp4jQAEzoMkoYAY0Al0gARLwHAEKmAFNRgEzoBHoAgmQgOcIUMDMaLKDcMPtbL6aDyfOjNvN0Asv+KjO009nO5IXeHrBx3Dsm1Vx05raz/iCrGUsNghoeixNc2Vy8YKPyo9+OtuLvMDTCz6ybzrbLx2tjQJmD6cX3oBe8JEfEvb6YXpne6HdveAj+6bzfdOxGilg9lB64Q3oBR/5IWGvH1LAnOeXuka+h9zl63ftFDC/0Vkn6uaZn9irwvWzveCjV1jST2e7K/tmePJ07K4pYI6hZEUkQAIkQAKBJEABCyRtXosESIAESMAxAhSw9FF2w5/fgemmnKNgI9Ic1h6/66adTWD/B5vk+/9L8PoRrChMd5bWzTy/dqy1/lmRv35qmOwPsJywPDDd4fpjA/1McUl5RsMmwx52yU9/Wao72tZrfH7txOv1Lvmo1drxMwLna3+uAtMNYXXz2R0u+eqvn1fCn7dS+VQPP+t7TNvejeKvn+rLa7BrYPo+mgl7zMfVaT/t+Pgfn4/q0yswNz+PnL7vi9ZHAfsnIhWtTbDOsN2wJbDbYfoBmlKq4Qf9UH0aprtMpwhYHV8H3ozXirBlsPqwIxdtiewfYMfPvLictv1pWGHYWtilsNjsu3HRM+z4mVK5fpnQdSmHYG4ImF0fj/s4XhSGzQPs+hmF6+uXKv2w1XbXnc9P2vQpvdPt+plSZ0n8sAVW2UA/9f3yOky/zGr5A/YcTBk7WeywVHF9HHY1LJ/Pt454Peakg8GsiwL2T/pt8afBsK6+/9JOqWV4Og01Fn/7GZYiYGkPWYU/9ISpoDldnPKzFBxbAWsDc0PA7PoZCb8GwGbAdM2dGwJm18dACZgdPxuAnQYcXe50R0ynPjt+pq5OgzyugN3hks92/NRz3/fx1M/RubA+sPUO+2rHR33f5IfpyEvLZ7BfYN847GPQqqOA/RO9Co4O2fv7/ks7ZesMPjjH4u8ZCVgr/N/nsIYw/abrdLHrp04jTYXVgmlH/8BpB3312fFTp2Zmw3rDOsHcEjA7PuptnoGt9L3qdLNb0112/LzR16eT8Fod9hvsWZhOfzpd7PiZ2hdt+zdh+h5zo9j1878+pvo5qmL2vAtO2vGxC/x5CaazSQVhi2H6Pn/DBT+DUiUF7J/Y7XSYlNoq4IcoWF/YQpda1gk/1TWd6tQP3Otg+13w1Y6fOtrSN54+a+gHM1XAKsG3PbAaMP3Q1WmarYax1HbQb+DNYPqcTp+FTPP9zWlX7bR56vfQal//THbaQV99dvzUL346tX2bry6dln0GNs9hX+34qK6oqN4C09R6B2D6SESf34dEoYD9sxntDNm1Nn02FgV7FZbR1KITnceun6l9GI1f9MPMDX/t+DkRPrWD6QhWn9nos7sPYTpycLLY8TGtH2Pxh8ymle34bcdPnSLWB/o6JadFZxb0bw/ZcSiDc+34mVKlBkTo7IVOI7pV7PiZdnruRTiZCNMvW04WOz6m9eML/GECTN/rIVEoYP9sxtz4kwZx6Ldo/Vat31h6wdal0+Jj8bfUH1b6ATsdNgXm9rccO37qQ/F42ClYCdgiWA9YSiSdk53bjp+p/eiHX9wagdnxUflpIIQGxJSGLYDdAEsd9OMUTzt+ajDAcphOxeq38TEwzTDhxtSxHT9TWOnMhT5/nuMUvHTqseOnjrzugenjBv0c1We0+p7X976TxY6P2ubFYfpe14hpFTCNlNYp75AoFLD0m1HDi7UzagfQ0YlGbg2B6Rteow5bwjQMXT+89FvXPph+W9RnNfrBkFrs+uF3fT7iRvHXT50T13lwDaVOmb93M6OIv36mZqYc3RIwvY6/Pmo02kiYjhL1mZ32G52qc6v466f6k9Lu2uYaIaujG30m5kax42c1OPQnTJ/TuvH8OPX9+uunfjbobIBGIer7SAXsSTdA2uibGsChX1q0aOTh/TC3PotcuvXMq6WABQU7L0oCJEACJGCXAAXMLkGeTwIkQAIkEBQCFLCgYOdFSYAESIAE7BKggNklmVFLZgAAAQRJREFUyPNJgARIgASCQoACFhTsvCgJkAAJkIBdAhQwuwR5PgmQAAmQQFAIUMCCgp0XJQESIAESsEuAAmaXIM8nARIgARIICgEKWFCw86IkQAIkQAJ2CVDA7BLk+SRAAiRAAkEhQAELCnZelARIgARIwC4BCphdgjyfBEiABEggKAQoYEHBzouSAAmQAAnYJUABs0uQ55MACZAACQSFAAUsKNh5URIgARIgAbsEKGB2CfJ8EiABEiCBoBCggAUFOy9KAiRAAiRglwAFzC5Bnk8CJEACJBAUAhSwoGDnRUmABEiABOwSoIDZJcjzSYAESIAEgkKAAhYU7LwoCZAACZCAXQL/Dzmfh2vsIODcAAAAAElFTkSuQmCC\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5edaff3d0>]"
+      ]
+     },
+     "execution_count": 129,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "outer_1_x_smooth = np.concatenate((outer_1_x[1:10], cx1[21:24], cx2[24:-1], cx2[:6], outer_1_x[13:26], cx3[8:15], cx4[15:22]))\n",
+    "outer_1_y_smooth = np.concatenate((outer_1_y[1:10], cy1[21:24], cy2[24:-1], cy2[:6], outer_1_y[13:26], cy3[8:15], cy4[15:22]))\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.plot(outer_1_x_smooth, outer_1_y_smooth)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Smoothen outer 2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 130,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(outer_2_x, outer_2_y)\n",
+    "for i in range(len(outer_2_x)):\n",
+    "    ax.text(outer_2_x[i], outer_2_y[i], f\"{i}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 131,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "radius1 = 0.005\n",
+    "radius2 = 0.0015\n",
+    "M1 = circle_m([outer_2_x[13],outer_2_y[13]], [outer_2_x[12],outer_2_y[12]], [outer_2_x[0],outer_2_y[0]], radius1)\n",
+    "M2 = circle_m([outer_2_x[0],outer_2_y[0]], [outer_2_x[13],outer_2_y[13]], [outer_2_x[1],outer_2_y[1]], radius2)\n",
+    "\n",
+    "cx1, cy1 = circle_points(M1, radius1, 30)\n",
+    "cx2, cy2 = circle_points(M2, radius2, 30)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 132,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(outer_2_x, outer_2_y)\n",
+    "for i in range(len(outer_2_x)):\n",
+    "    ax.text(outer_2_x[i], outer_2_y[i], f\"{i}\")\n",
+    "ax.plot(cx1, cy1)\n",
+    "ax.plot(cx2, cy2)\n",
+    "for i in range(len(cx1)):\n",
+    "    ax.text(cx1[i], cy1[i], f\"{i}\")\n",
+    "for i in range(len(cx2)):\n",
+    "    ax.text(cx2[i], cy2[i], f\"{i}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 133,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5ede70c10>]"
+      ]
+     },
+     "execution_count": 133,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "outer_2_x_smooth = np.concatenate((outer_2_x[1:13], cx1[5:10], cx2[9:21]))\n",
+    "outer_2_y_smooth = np.concatenate((outer_2_y[1:13], cy1[5:10], cy2[9:21]))\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.plot(outer_2_x_smooth, outer_2_y_smooth)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 134,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.plot(inner_x_smooth, inner_y_smooth, c='b')\n",
+    "ax.plot(outer_1_x_smooth, outer_1_y_smooth, c='b')\n",
+    "ax.plot(outer_2_x_smooth, outer_2_y_smooth, c='b')\n",
+    "ax.set_aspect('equal')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 135,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 11.71 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 21.16 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 55.19 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "(<Figure size 432x288 with 1 Axes>, <AxesSubplot:>)"
+      ]
+     },
+     "execution_count": 135,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "filename = \"design_v4rdso1_inner.txt\"\n",
+    "hole_to_SC_curves(inner_x_smooth, inner_y_smooth, filename, num_holes=36)\n",
+    "filename = \"design_v4rdso1_outer_1.txt\"\n",
+    "hole_to_SC_curves(outer_1_x_smooth, outer_1_y_smooth, filename, num_holes=36)\n",
+    "filename = \"design_v4rdso1_outer_2.txt\"\n",
+    "hole_to_SC_curves(outer_2_x_smooth, outer_2_y_smooth, filename, num_holes=36)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Lower frequency, higher deformation"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# V4rds but with stress optimization L2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 136,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbAAAAEgCAYAAADVKCZpAAAgAElEQVR4Xu2dB5hURdaGD2HIQXKOIoKCCTFgWhWzrrquiqJizhjWnHPW37wmzGHNu2YxoqKiCCIIqATJSM45/eetnhqbcQamgRluw1c89XQz3ffeul/drq9OLmVqQkAICAEhIASyEIFSWThmDVkICAEhIASEgInA9BAIASEgBIRAViIgAsvKadOghYAQEAJCQASmZ0AICAEhIASyEgERWFZOmwYtBISAEBACIjA9A0JACAgBIZCVCIjAsnLaNGghIASEgBAQgekZEAJCQAgIgaxEQASWldOmQQsBISAEhIAITM+AEBACQkAIZCUCIrCsnDYNWggIASEgBERgegaEgBAQAkIgKxEQgWXltGnQQkAICAEhIALTMyAEhIAQEAJZiYAILCunTYMWAkJACAgBEZieASEgBISAEMhKBERgWTltGrQQEAJCQAiIwPQMCAEhIASEQFYiIALLymnToIWAEBACQkAEpmdACAgBISAEshIBEVhWTpsGLQSEgBAQAiIwPQNCQAgIASGQlQiIwLJy2jRoISAEhIAQEIHpGRACQkAICIGsREAElpXTpkELASEgBISACEzPgBAQAkJACGQlAiKwrJw2DVoICAEhIAREYHoGhIAQEAJCICsREIFl5bRp0EJACAgBISAC0zMgBISAEBACWYmACCwrp02DFgJCQAgIARGYngEhIASEgBDISgREYFk5bRq0EBACQkAIiMD0DAgBISAEhEBWIiACy8pp06CFgBAQAkJABKZnQAgIASEgBLISARFYVk6bBi0EhIAQEAIiMD0DQkAICAEhkJUIiMCycto0aCEgBISAEBCB6RkQAkJACAiBrERABJaV06ZBCwEhIASEgAhMz4AQEAJCQAhkJQIisKycNg1aCAgBISAERGB6BoSAEBACQiArERCBZeW0adBCQAgIASEgAtMzIASEgBAQAlmJgAgsK6dNgxYCQkAICAERmJ4BISAEhIAQyEoERGBZOW0atBAQAkJACIjA9AwIASEgBIRAViIgAsvKadOghYAQEAJCQASmZ0AICAEhIASyEgERWFZOmwYtBISAEBACIjA9A0JACAgBIZCVCIjAsnLaNGghIASEgBAQgekZEAJCQAgIgaxEQASWldOmQQsBISAEhIAITM+AEBACQkAIZCUCIrCsnDYNWggIASEgBERgegaEgBAQAkIgKxEQgWXltGnQQkAICAEhIALTMyAEhIAQEAJZiYAILCunTYMWAkJACAgBEZieASEgBISAEMhKBERgWTltGrQQEAJCQAiIwPQMCAEhIASEQFYiIALLymnToIWAEBACQkAEpmdACAgBISAEshIBEVhWTpsGLQSEgBAQAiIwPQNCQAgIASGQlQiIwLJy2jRoISAEhIAQEIHpGRACQkAICIGsREAElpXTpkELASEgBISACEzPgBAQAkJACGQlAiKwrJw2DVoICAEhIAREYHoGhIAQEAJCICsREIFl5bRp0EJACAgBISAC0zMgBISAEBACWYmACCwrp02DFgJCQAgIARGYngEhIASEgBDISgREYFk5bRq0EBACQkAIiMD0DAgBISAEhEBWIiACy8pp06CFgBAQAkJABKZnQAgIASEgBLISARFYVk6bBi0EhIAQEAIiMD0DQkAICAEhkJUIiMCycto0aCEgBISAEBCB6RkQAkJACAiBrERABJaV06ZBCwEhIASEgAhMz4AQEAJCQAhkJQIisKycNg1aCAgBISAERGB6BoSAEBACQiArERCBZeW0adBCQAgIASEgAtMzIASEgBAQAlmJgAgsK6dNg85iBDbxsffw3s77Cu8ne1/g/Qnvm3kv7/0P78d6v8D7Ft6beK/sfZn3Pb1/672793Ny//aev16axZho6EJgjRAQga0RbDpICNjmjsEraTi09PfXen8u9+/8v4r3WbkkA1HN9/6x98Xef/R+Yu5nr/prae8ve5/g/TLvh3qf6f1Z7195b+t9rvd7vW/r/Trv071DcBzbzft+3k/zPsU77Urv7+e+14sQ2OAQEIFtcFOqG1oPCJTxa473vqN3pCKIBcKBwIZ7v8Z7Je+feW/gvaH3k7y3yP3sU39t772e9y7eD/GOBFbd+wDvkOEY73t5H+YdwkOS4xVprlzu+ZHYILm7vasJgQ0eARHYBj/FusG1RKAwSQvCut47RIU6D8LZxfuvuQTU0187ee/lnXPQ5ngf6n2I9+29N/Le2Pu+3pG+lnrP8f6m91O8o1J83Ps073t4f8n7+d5RIaJW/M37Qu8Xe+/r/frcc2zjr+kqSr5Pu8g75FbH+9Tcv+lFCGQtAhssgdWqVWtF8+bNs3ZiNPCSQ2DhwoU2cuTIvAsuWrTIGjZsaEuWLLGZM2da6dKlrXz58ta0aVMbMmSItWnTxpYvX26lSpWy0aNHW5kyZaxatWpWt25dGzBggLVu3Tr8vUKFCjZ9+nTzZ9GaNGliv/76qy1YsCAcP3fuXBs/frzVq1fPuN6MGTPC33k/bty4cMwmm2xiv/zyS3itUqWKLV68OIyF7y5btixcc968eWGc7du3t8mTJ9ukSZPyxsM98H3a77//bnPmzLEVK1bYpptuGo6bNQvtplnZsmWN30q5cghyahs7Av369WNzwyYn8W2DJbAOHTqs+OGHHxI/ARpgySEAgRx99NF5F4S0brzxRps2bZq99dZbYbGvU6dOICGeHb6/1157hQX+sssuCyQA6Xz99dd559hjjz3sp59+Ct+FjCCbTz75xHbaaafwvf33399OOOGEQDb77rtv6FtssYX9/e9/t//7v/+zXXfd1b766iurUaNGID0IBrL629/+Zk8++aTtuOOOBsH6ohKuf/vttwdS/P777+2bb74Jn1evXt1OOeUUO+uss2yfffaxESNG2LXXXmsTJ060p556yrp162Y///xzeH/ooYfap59+Gu6TMdEeeOCBQMyPPvpoyU2GrpRYBHxj1s8Hh4Yg8U0Elvgp0gALQqAwMho+fLg99thjgXRoSEm33nqrXXAB5iGze+65xy6++GL7448/bOutt7bvvvsukEdczM8++2x78803w+fp7b///W847sILL7Rzzz0376N27dpZ5cqVw3lom2++ub366quBKL799ttARD169AjE895779luu+0W/s+49txzTzv22GPt3XffDeN9/fXXg/R1/PHHW9euXe2uu+4yzl+xYkXr27evXX/99UFyql27tt12221BOvztt98CCW6//fbhPk8//fRAkBAcBDZ48GDbdtttA3FDVEhakDPXO/XUUwOxQYicA8nsnXfeCZIY759++ulAyGobFwIisATMtySwBExCIUMojHxYXFm4o3qORf7888+3f//730G1RuO1QYMGQRJ68MEH7eGHHw4qs1GjRgUpgkUXCQayQc3WqFGjQC7NmjWzsWPHhkUbtdzdd99t991330rSFOeHCCAMpKL0dtBBB9mXX35pECSSVmyoDc8888wgyc1asMT+ddHFVq5yNfvi04+sSev2tmjZCltSqpyrDOdZuwO62uxpU+zrp2+2uVPGW6Va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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5ed0b5910>]"
+      ]
+     },
+     "execution_count": 136,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "drx = copy.deepcopy(filterX)\n",
+    "dry = copy.deepcopy(filterY)\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(drx, dry)\n",
+    "for i in range(len(drx)):\n",
+    "    ax.text(drx[i], dry[i], f\"{i}\")\n",
+    "\n",
+    "x0 = []\n",
+    "y0 = []\n",
+    "for i in range(len(drx)):\n",
+    "    x0n, y0n = rot([drx[i],dry[i]],-10)\n",
+    "    x0.append(x0n)\n",
+    "    y0.append(y0n)\n",
+    "for i in range(len(x0)):\n",
+    "    ax.text(x0[i], y0[i], f\"{i}\")\n",
+    "ax.plot(x0,y0)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Select partitioning"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 137,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#inner stays the same\n",
+    "inner_x = np.concatenate((drx[76:],drx[:33],[drx[76]+0.01*(drx[32] - drx[76])]))\n",
+    "inner_y = np.concatenate((dry[76:],dry[:33],[dry[76]+0.01*(dry[32] - dry[76])]))\n",
+    "#outer is now two holes\n",
+    "outer_1_x = np.concatenate((drx[33:45], drx[63:76],[drx[33] + 0.01*(drx[33] - drx[75])]))\n",
+    "outer_1_y = np.concatenate((dry[33:45], dry[63:76],[dry[33] + 0.01*(dry[33] - dry[75])]))\n",
+    "outer_2_x = np.concatenate((drx[45:63], [drx[45] + 0.01*(drx[62] - drx[45])]))\n",
+    "outer_2_y = np.concatenate((dry[45:63], [dry[45] + 0.01*(dry[62] - dry[45])]))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## inner smoothening"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 138,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbAAAAEgCAYAAADVKCZpAAAgAElEQVR4Xu2dCZyN1RvHH7MYZmHsa3bZZQkt9j0phZAKSSpb5Z9ki0hEC0lFSEopWih79t0g+24wDGYMZhjM7v885947runemTv33hn3fd/fmc/zucu8yznf59z3955znvecHIQEAiAAAiAAAhokkEODeUaWQQAEQAAEQIAgYKgEIAACIAACmiQAAdOk25BpEAABEAABCBjqAAiAAAiAgCYJQMA06TZkGgRAAARAAAKGOgACIAACIKBJAhAwTboNmQYBEAABEICAoQ6AAAiAAAhokgAETJNuQ6ZBAARAAAQgYKgDIAACIAACmiQAAdOk25BpEAABEAABCBjqAAiAAAiAgCYJQMA06TZkGgRAAARAAAKGOgACIAACIKBJAhAwTboNmQYBEAABEICAoQ6AAAiAAAhokgAETJNuQ6ZBAARAAAQgYKgDIAACIAACmiQAAdOk25BpEAABEAABCBjqAAiAAAiAgCYJQMA06TZkGgRAAARAAAKGOgACIAACIKBJAhAwTboNmQYBEAABEICAoQ6AAAiAAAhokgAETJNuQ6ZBAARAAAQgYKgDIAACIAACmiQAAdOk25BpEAABEAABCBjqAAiAAAiAgCYJQMA06TZkGgRAAARAAAKGOgACIAACIKBJAhAwTboNmQYBEAABEICAoQ6AAAiAAAhokgAETJNuQ6ZBAARAAAQgYKgDIAACIAACmiQAAdOk25BpEAABEAABCBjqAAiAAAiAgCYJQMA06TZkGgRAAARAAAKGOgACIAACIKBJAhAwTboNmQYBEAABEICAoQ6AAAiAAAhokgAETJNuQ6ZBAARAAAQgYKgDIAACIAACmiQAAdOk25BpEAABEAABCBjqAAiAAAiAgCYJQMA06TZkGgRAAARAAAKGOgACIAACIKBJAhAwTboNmQYBEAABEICAoQ6AAAiAAAhokgAETJNuQ6ZBAARAAAQgYKgDIAACIAACmiQAAdOk25BpEAABEAABCBjqAAiAAAiAgCYJQMA06TZkGgRAAARAAAKGOgACIAACIKBJAhAwTboNmQYBEAABEICAoQ6AAAiAAAhokgAETJNuQ6ZBAARAAAQgYKgDIAACIAACmiQAAdOk25BpEAABEAABCBjqAAiAAAiAgCYJQMA06TZkGgRA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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(inner_x, inner_y)\n",
+    "for i in range(len(inner_x)):\n",
+    "    ax.text(inner_x[i], inner_y[i], f\"{i}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 139,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "radius1 = 0.003\n",
+    "M1 = circle_m([inner_x[37],inner_y[37]], [inner_x[36],inner_y[36]], [inner_x[38],inner_y[38]], radius1)\n",
+    "radius2 = 0.0015\n",
+    "M2 = circle_m([inner_x[0],inner_y[0]], [inner_x[37],inner_y[37]], [inner_x[1],inner_y[1]], radius2)\n",
+    "\n",
+    "cx1, cy1 = circle_points(M1, radius1, 30)\n",
+    "cx2, cy2 = circle_points(M2, radius2, 30)\n",
+    "\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(inner_x, inner_y)\n",
+    "for i in range(len(inner_x)):\n",
+    "    ax.text(inner_x[i], inner_y[i], f\"{i}\")\n",
+    "ax.plot(cx1, cy1)\n",
+    "ax.plot(cx2, cy2)\n",
+    "for i in range(len(cx1)):\n",
+    "    ax.text(cx1[i], cy1[i], f\"{i}\")\n",
+    "for i in range(len(cx2)):\n",
+    "    ax.text(cx2[i], cy2[i], f\"{i}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 140,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5ed256e20>]"
+      ]
+     },
+     "execution_count": 140,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "#inner_x_smooth = np.concatenate((inner_x[1:36], cx1[22:29], cx2[28:], cx2[:9]))\n",
+    "#inner_y_smooth = np.concatenate((inner_y[1:36], cy1[22:29], cy2[28:], cy2[:9]))\n",
+    "inner_x_smooth = np.concatenate((inner_x[1:30], [inner_x[34]-0.3 * (inner_y[34]-inner_y[35])], cx1[24:29], cx2[28:], cx2[:9]))\n",
+    "inner_y_smooth = np.concatenate((inner_y[1:30], [inner_y[34]+0.3 * (inner_x[34]-inner_x[35])], cy1[24:29], cy2[28:], cy2[:9]))\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(inner_x_smooth, inner_y_smooth)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## outer 1 smoothening"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 141,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(outer_1_x, outer_1_y)\n",
+    "for i in range(len(outer_1_x)):\n",
+    "    ax.text(outer_1_x[i], outer_1_y[i], f\"{i}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 142,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "radius1 = 0.003\n",
+    "M1 = circle_m([outer_1_x[11],outer_1_y[11]], [outer_1_x[10],outer_1_y[10]], [outer_1_x[12],outer_1_y[12]], radius1)\n",
+    "radius2 = 0.0015\n",
+    "M2 = circle_m([outer_1_x[12],outer_1_y[12]], [outer_1_x[11],outer_1_y[1]], [outer_1_x[13],outer_1_y[13]], radius2)\n",
+    "radius3 = 0.0025\n",
+    "M3 = circle_m([outer_1_x[24],outer_1_y[24]], [outer_1_x[23],outer_1_y[23]], [outer_1_x[0],outer_1_y[0]], radius3)\n",
+    "radius4 = 0.002\n",
+    "M4 = circle_m([outer_1_x[0],outer_1_y[0]], [outer_1_x[24],outer_1_y[24]], [outer_1_x[1],outer_1_y[1]], radius4)\n",
+    "\n",
+    "cx1, cy1 = circle_points(M1, radius1, 30)\n",
+    "cx2, cy2 = circle_points(M2, radius2, 30)\n",
+    "cx3, cy3 = circle_points(M3, radius3, 30)\n",
+    "cx4, cy4 = circle_points(M4, radius4, 30)\n",
+    "\n",
+    "fig, ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(outer_1_x, outer_1_y)\n",
+    "for i in range(len(outer_1_x)):\n",
+    "    ax.text(outer_1_x[i], outer_1_y[i], f\"{i}\")\n",
+    "ax.plot(cx1, cy1)\n",
+    "ax.plot(cx2, cy2)\n",
+    "ax.plot(cx3, cy3)\n",
+    "ax.plot(cx4, cy4)\n",
+    "for i in range(len(cx1)):\n",
+    "    ax.text(cx1[i], cy1[i], f\"{i}\")\n",
+    "for i in range(len(cx2)):\n",
+    "    ax.text(cx2[i], cy2[i], f\"{i}\")\n",
+    "for i in range(len(cx3)):\n",
+    "    ax.text(cx3[i], cy3[i], f\"{i}\")\n",
+    "for i in range(len(cx4)):\n",
+    "    ax.text(cx4[i], cy4[i], f\"{i}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 143,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbAAAAEgCAYAAADVKCZpAAAgAElEQVR4Xu2dCZwU1bX/j8gOwzbswsguLqgB2VSUNeCePE3impDEuDw15vlcQtSnfxKVGOOaRY0ajCb6jOYZFUVlGVFBNhVZZIeRHYZhmWHY8f/7VVdD084MM93V3XWnf9fPsaqb6qpT33Onf31vnXvvUaYiAiIgAiIgAg4SOMpBn+WyCIiACIiACJgETJVABERABETASQISMCfDJqdFQAREQAQkYKoDIiACIiACThKQgDkZNjktAiIgAiIgAVMdEAEREAERcJKABMzJsMlpERABERABCZjqgAiIgAiIgJMEJGBOhk1Oi4AIiIAISMBUB0RABERABJwkIAFzMmxyWgREQAREQAKmOiACIiACIuAkAQmYk2GT0yIgAiIgAhIw1QEREAEREAEnCUjAnAybnBYBERABEZCAqQ6IgAiIgAg4SUAC5mTY5LQIiIAIiIAETHVABERABETASQISMCfDJqdFQAREQAQkYKoDIiACIiACThKQgDkZNjktAiIgAiIgAVMdEAEREAERcJKABMzJsMlpERABERABCZjqgAiIgAiIgJMEJGBOhk1Oi4AIiIAISMBUB0RABERABJwkIAFzMmxyWgREQAREQAKmOiACIiACIuAkAQmYk2GT0yIgAiIgAhIw1QEREAEREAEnCUjAnAybnBYBERABEZCAqQ6IgAiIgAg4SUAC5mTY5LQIiIAIiIAETHVABERABETASQISMCfDJqdFQAREQAQkYKoDIiACIiACThKQgDkZNjktAiIgAiIgAVMdEAEREAERcJKABMzJsMlpERABERABCZjqgAiIgAiIgJMEJGBOhk1Oi4AIiIAISMBUB0RABERABJwkIAFzMmxyWgREQAREQAKmOiACIiACIuAkAQmYk2GT0yIgAiIgAhIw1QEREAEREAEnCUjAnAybnBYBERABEZCAqQ6IgAiIgAg4SUAC5mTY5LQIiIAIiIAETHVABERABETASQISMCfDJqdFQAREQAQkYKoDIiACIiACThKQgDkZNjktAiIgAiIgAVMdEAEREAERcJKABMzJsMlpERABERABCZjqgAiIgAiIgJMEJGBOhk1Oi4AIiIAISMBUB0RABERABJwkIAFzMmxyWgREQAREQAKmOiACIiACIuAkAQmYk2GT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00hnSdT/YXDy9zBmUrIu/gGWidlSEvU/ljG5Z0LA6EOi/jPj8ykYW5B8nscfQensfovyS9R/fj5ah1h/mIXLVgyfiaWzJON/Bzj6MYzPgtP57DqdfFJ2reoiYCkDpBOLgAiIgAiEk4AELJxxkVciIAIiIAJHICABUxURAREQARFwkoAEzMmwyWkREAEREAEJmOqACIiACIiAkwQkYE6GTU6LgAiIgAhIwFQHREAEREAEnCQgAXMybHJaBERABERAAqY6IAIiIAIi4CQBCZiTYZPTIiACIiACEjDVAREQAREQAScJSMCcDJucFgEREAERkICpDoiACIiACDhJQALmZNjktAiIgAiIgARMdUAEREAERMBJAhIwJ8Mmp0VABERABCRgqgMiIAIiIAJOEpCAORk2OS0CIiACIiABUx0QAREQARFwkoAEzMmwyWkREAEREAEJmOqACIiACIiAkwQkYE6GTU6LgAiIgAhIwFQHREAEREAEnCQgAXMybHJaBERABERAAqY6IAIiIAIi4CQBCZiTYZPTIiACIiACEjDVAREQAREQAScJSMCcDJucFgEREAERkICpDoiACIiACDhJQALmZNjktAiIgAiIgARMdUAEREAERMBJAhIwJ8Mmp0VABERABCRgqgMiIAIiIAJOEpCAORk2OS0CIiACIiABUx0QAREQARFwkoAEzMmwyWkREAEREAEJmOqACIiACIiAkwQkYE6GTU6LgAiIgAhIwFQHREAEREAEnCQgAXMybHJaBERABERAAqY6IAIiIAIi4CQBCZiTYZPTIiACIiACEjDVAREQAREQAScJSMCcDJucFgEREAERkICpDoiACIiACDhJQALmZNjktAiIgAiIgARMdUAEREAERMBJAhIwJ8Mmp0VABERABCRgqgMiIAIiIAJOEpCAORk2OS0CIiACIiABUx0QAREQARFwkoAEzMmwyWkREAEREAEJmOqACIiACIiAkwQkYE6GTU6LgAiIgAhIwFQHREAEREAEnCQgAXMybHJaBERABERAAqY6IAIiIAIi4CQBCZiTYZPTIiACIiACEjDVAREQAREQAScJSMCcDJucFgEREAERkICpDoiACIiACDhJQALmZNjktAiIgAiIgARMdUAEREAERMBJAhIwJ8Mmp0VABERABCRgqgMiIAIiIAJOEpCAORk2OS0CIiACIiABUx0QAREQARFwkoAEzMmwyWkREAEREAEJmOqACIiACIiAkwQkYE6GTU6LgAiIgAhIwFQHREAEREAEnCTw/wEhrKsRJ1VeGgAAAABJRU5ErkJggg==\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5ec9c7280>]"
+      ]
+     },
+     "execution_count": 143,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "outer_1_x_smooth = np.concatenate((outer_1_x[1:11], cx1[21:28], cx2[27:], cx2[:7], outer_1_x[13:24], cx3[8:15], cx4[14:23]))\n",
+    "outer_1_y_smooth = np.concatenate((outer_1_y[1:11], cy1[21:28], cy2[27:], cy2[:7], outer_1_y[13:24], cy3[8:15], cy4[14:23]))\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(outer_1_x_smooth, outer_1_y_smooth)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## outer 2 smoothening"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 144,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(outer_2_x, outer_2_y)\n",
+    "for i in range(len(outer_2_x)):\n",
+    "    ax.text(outer_2_x[i], outer_2_y[i], f\"{i}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 145,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "radius1 = 0.002\n",
+    "M1 = circle_m([outer_2_x[17],outer_2_y[17]], [outer_2_x[16],outer_2_y[16]], [outer_2_x[0],outer_2_y[0]], radius1)\n",
+    "radius2 = 0.002\n",
+    "M2 = circle_m([outer_2_x[0],outer_2_y[0]], [outer_2_x[17],outer_2_y[17]], [outer_2_x[1],outer_2_y[1]], radius2)\n",
+    "\n",
+    "cx1, cy1 = circle_points(M1, radius1, 30)\n",
+    "cx2, cy2 = circle_points(M2, radius2, 30)\n",
+    "\n",
+    "\n",
+    "ax.plot(cx1, cy1)\n",
+    "ax.plot(cx2, cy2)\n",
+    "for i in range(len(cx1)):\n",
+    "    ax.text(cx1[i], cy1[i], f\"{i}\")\n",
+    "for i in range(len(cx2)):\n",
+    "    ax.text(cx2[i], cy2[i], f\"{i}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 146,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbAAAAEgCAYAAADVKCZpAAAgAElEQVR4Xu2dB3hUVRbHD72GFnoJvUnv0psComLDhqKo6Lr2AiiiLusugmVRcS2gKPayKIqoKC2C9I6AtAiB0DuEJJAE9n9e3miMSZjy3uS9ef/7feebyeSVM797Z/5z7z333HzCQgIkQAIkQAIuJJDPhT7TZRIgARIgARIQChgbAQmQAAmQgCsJUMBcWW10mgRIgARIgALGNkACJEACJOBKAhQwV1YbnSYBEiABEqCAsQ2QAAmQAAm4kgAFzJXVRqdJgARIgAQoYGwDJEACJEACriRAAXNltdFpEiABEiABChjbAAmQAAmQgCsJUMBcWW10mgRIgARIgALGNkACJEACJOBKAhQwV1YbnSYBEiABEqCAsQ2QAAmQAAm4kgAFzJXVRqdJgARIgAQoYGwDJEACJEACriRAAXNltdFpEiABEiABChjbAAmQAAmQgCsJUMBcWW10mgRIgARIgALGNkACJEACJOBKAhQwV1YbnSYBEiABEqCAsQ2QAAmQAAm4kgAFzJXVRqdJgARIgAQoYGwDJEACJEACriRAAXNltdFpEiABEiABChjbAAmQAAmQgCsJUMBcWW10mgRIgARIgALGNkACJEACJOBKAhQwV1YbnSYBEiABEqCAsQ2QAAmQAAm4kgAFzJXVRqdJgARIgAQoYGwDJEACJEACriRAAXNltdFpEiABEiABChjbAAmQAAmQgCsJUMBcWW10mgRIgARIgALGNkACJEACJOBKAhQwV1YbnSYBEiABEqCAsQ2QAAmQAAm4kgAFzJXVRqdJgARIgAQoYGwDJEACJEACriRAAXNltdFpEiABEiABChjbAAmQAAmQgCsJUMBcWW10mgRIgARIgALGNkACJEACJOBKAhErYNHR0edq1arlykqh0yRAAiSQVwRWrlx5CPeukFf3D+S+EStgbdq0ObdixYpAWPBYEiABEvA8gXz58q0EhLZuAEEBc0Mt0UcSIAESCBMBCliYQOd2G/bAHFAJdIEESMB1BChgDqgyCpgDKoEukAAJuI4ABcwBVUYBc0Al0AUSIAHXEaCAOaDKKGAOqAS6QAIk4DoCFDAHVBkFLLhKOJmSKseTU+XU6XRJPJ0qRQsVkLoVShqPLCRAApFPgALmgDqmgPlXCSmp6bJs+xGZv+WgzN96ULbsT/zLifkQqxpTrrg0qBQl/ZtVlkuaVqGg+YeXR5GA6whQwBxQZRSw3CshNf2sfLp8l7w6Z6scOHlaChfIL+1ql5VOdctLhZJFpGTRglKiSEFJTEmTrQdOwhJl7a5jknA0WUoXKyTXtK4uN18YI3XQO2MhARKIHAIUMAfUJQUs50qYuX6vjP1+k8QfTpK2NcvK3d3rSqd60VK8cMFca+7s2XOy5LfD8tGynfLjhn2Shr/7XFBJ/obzW8eUdUCt0wUSIIFQCVDAQiVowfkUsL9CVAF64cfN8kZsnDSqHCUj+jWUng0rChpswMQPotf2/uIdsHhjzqx97XIQwjrSo0FFyZ8/8OsF7ABPIAESsIUABcwWrIFdlAL2Z17JZ9Llkc/XyPfr98mgDjHyzwFNpBCGDUMtp06nGUORkxf8JnuOp2CerKTc1a2uDGhRVQoXDP36ofrH80mABAIj4HUB6wdcr8A0bO1t2Lgc8F2D16fC2sF8SQub4/lEWCnYWfN/KXiMhVWBJZvX6oPHA7lVCwXsDzrp6HndNmW5LECQxqj+jeWOLrWD6nXlxlvn1Gas2yMTf/pNNu07KVVKFzXuc0P7GCmJuTQWEiABdxDwsoCpaG2BXQxLgC2H3QjbmKXqovD3t7DCsPtMAdNvuVWwwbC1sGjYMVi6KWDDzOP8agUUsD8wvTJ7q7w0e4uMuaqp3NShpl/8gj3o3LlzEouIxok/xWG+7IhEIRhk8IU1ZUjnWlIxqmiwl+V5JEACYSLgZQHrCMajYX1N1iPNx7FZ2L+Mv2fBhsN8wtQfzwfBbs6mnmIzHedXNVLAMjAt3HZIbp68VK5sWU3GX9fC8p5XbpWxBlGLk+bHGcOWhfLnl2vaVJM7u9Zh5KJfLZgHkUDeEPCygA0Ech1CHGqi195UB5j2snylNZ6MgukQYmZhegh/t4FVhOleNJ/CnjdP0uO0R6a9sS9g/4ady616KWAiOqzX44VYKVa4gEy/r/N5owzt+rhsP3RK3sIc2dSVCYZPfS+ojMjFOtKKkYt2Ied1SSBoAhSwnAVMZ/XnwobAdmQRMO2J3QvTObEk2BzYk+ZjNTzuhunQowrYh7D3s6mhu/CamsTExLSJj48PuhIj4cRpqxPk4c/WyuRb20rvxpXy/C1p5OJ7izRycYecwPoyjVzUHlmvRhWlACMX87x+6AAJKAEvC9j5hhBLg08czJfuoTKeH4ENgNWDXQK71WxGT+FRAzheyNKshuBv3Wwtc6/uLy3P6z0wnYu65JUFogEcPzzUzVGh7YkauYi1ZJN/3i57EblYvWwxY27u+nY1pFwJnRZlIQESyCsCXhYwDcTQII7eMO0xaRCHzmttyKEyYvG6bw5MV8Jqr6sL7AxsJuwl2A+wMjDd5roQ7BPYbNibuVWw1wXsJwRS3PrOMnnx2hYysE31vPos5HpfHU78ccN+o0e2FOmsNOz+suZV5JaOtaRlDa1yFhIggXAT8LKAKWsNxtAgDY1IfAc2BvYMTEPlp2epjFj8nTm6UAM4NPBD57e+g42AlYDNh6l46TVVvB6B6XxYjsXrAnbn+ytkVfxRWTSylxQp6PxEvJsRev/Bkh0ybdVuOYU1a82rlzaiFy/HejImEg73Vxjv52UCXhcwR9S9lwVs7/Fk6TxurrGg+PFLGjmiPvx1QrPhfwkR+2BJvGxD/sUyxQvJ9W1rIO9iTamBhMIsJEAC9hKggNnL16+re1nAXpq1RV5Bkt75w3tKTLQ7v/R1Dm9x3GEjVdWsX/fLWfytaa8Gd6wp3etXcNScnl8NkgeRgEsIUMAcUFFeFbA0zCt1eW6eNECuw/dvb++AmgjdBe1Rfrx0p3yybJccSjwtNSHKNyPo49q21dFDY9BH6IR5BRL4gwAFzAGtwasCplni7/pgpUwc3Eb6NtEgz8gpZ9LOYlH0XvkAvbIVmN8rWii/kXNRgz6aVtMAVxYSIIFQCVDAQiVowfleFTCNPNy074QsfKyXFLQgWa8FVWHLJTbuOWEEfXy1eo8kY1POVjFlIGQ1seFmFVcErdgChRclAQsIUMAsgBjqJbwoYDuxv1f3F+fJA73qy8MXNwgVoSvO161cNMPHhwj60Iwf0VhHpuvJbkLQR7UyxVzxHugkCTiJAAXMAbXhRQF7buYmI4nuwsd7IRu8t768da+zn5H3UYM+5m7ab7RAzT6ivbIu9cqHNQekA5o/XSCBoAlQwIJGZ92JXhMwnR/qOHaOtMYOy2/doolKvFsSjibJRwj6+Az7lB05dUbqlC9hhOFfgwXdpYvpckIWEiCBnAhQwBzQNrwmYN+s3SP3f7JaptzWTnog3JwFecgwN/bdL3uNXplmxi9WqIBc2aqa0StrXEW3nGMhARLISoAC5oA24TUBu2HSYkk4mmys/crPxLh/aYG/JBw3UlZNh9CfRm+1Xa2yWFNWS/ohUpM7RzvgA0sXHEOAAuaAqvCSgGnGiovG/yQj+jWUe3poTmSWnAgcxZDi/1buQtDHTtl5JEkqRBWRGxH0MQjryipjF2kWEvA6AQqYA1qAlwTsmW82GiHlix7vbXwhs5yfgAZ9aMJj7ZXpDtL58+WTPhdUMjJ9dKwTzaCP8yPkERFKgALmgIr1ioDpPE/7MbOlW4MK8t9BulcoS6AEdPnBh0vj5fMVu+RYUqrUq1gS27vEyNWtEPSBXIwsJOAlAhQwB9S2VwRM10AN+99a+fjODtKpbnkHkHevC/pjQOfINIJxLYI+NNPH5c2rYngxxtjeBR9s9745ek4CfhKggPkJys7DvCJgV72+UI6j1zDn0e78grWwQa3ffdwQsq/X7JYkbO9yAaIWb7owRq5oWU1KFtFt71hIIDIJUMAcUK9eEDBNp9R/wgJ58tLGMrRrHQdQjzwXdHuXr9dk9Mp+3XtCShTOCMXXXlmTqsy/GHk1zndEAXNAG/CCgD351S+Yt0mQZU/0ZlZ2m9ucbu+yGsOKmhVf19xpKL4OK+pc2WUYZiwGYWMhgUggQAFzQC1GuoAlnk6TDgje6Nu0soy/rqUDiHvHBR2y/WJVAnpl8RJ38JSUKlpQrm5d3RCz+pWivAOC7zQiCVDAHFCtkS5g2hN4Ytov8sXfO0kbpI9iCT8B7ZUt237EGF7UbV5S089J+9rlDCHrhx8WRQqyVxb+WuEdQyVAAQuVoAXnR7KA6RfnZa/+LOlYy/T9g10ZvGFBewn1ErrRpkaEfrJsp8QjLL8csuJfi9yLN7aPkVrIxchCAm4hQAFzQE1FsoBpXr8rX1so/7qyqQxGkloW5xDQBdIL4w7JR8j0MevX/caPjK71yxu9Ms2OXyiC92hzTi3Qk1AIUMBCoWfRuZEsYMOx7utbJKldiuCNqKJcaGtRk7H8MvtPpMjnyIivvbI9x1OMLCk3IG3VDeiVca8yy3HzghYRoIBZBDKUy0SqgGkAQYexs+UqZIkYe3WzUBDx3DAR0F5Y7OYDxlzZPDzqcuie2DFAQ/F154ACTL4cpprgbfwhQAHzh5LNx0SqgL27cLv8E7kPZ9zfRZpW4zokm5uR5ZfXvcp0n7JPYQdPnjZ6Ytor012kK5ZiMmHLgfOCAROggAWMzPoTIlHANHjj4pfmSwlkgvj63s7WQ+MVw0YgNf2szN64Xz7G8OKCrYekIHphFyOZsPbKOiMlGLfECVtV8EZZCFDAHNAkIlHAlv52WK6ftESeH9hcrmtbwwGU6YIVBHYcOmXMk2ky4aMYIq4ZXVwGYZ5sIKIYo0tydwErGPMa/hOggPnPyrYjI1HAHsCOyzqHsuyJi5j5wbaWk3cXPp2WLjPX7zPmynR9WWFELOp6Mo1g1PVlTCacd3XjpTtTwBxQ25EmYIexzqjj2LnGENPoAU0cQJgu2Elg6/6ThpBpxo+TKWnc4sVO2Lz2nwhQwBzQICJNwCb+FCdjv98kPz7cTRowXZEDWlh4XEhGJvwZ6zKSCev6P98WL7d1ri0XVC0VHid4F08RoIA5oLojScB0cWzP/8RKpaii8vndHR1Aly7kBQHd4kWDPqat2i3J2LusU91ouaNLbSMkn0EfeVEjkXlPCpgD6jWSBGzB1oMyePIyeeWGlsZ+VCzeJqBrAT9ZvlPeW7RD9mKBdB2kqrqtcy25BkEfxQtzrzJvt47Q3z0FLHSGIV8hkgTs7g9WyrIdR2TxyF5MEBtyy4icC2go/vcI+pi84DdZm3BcShcrZMyR3tqxllQuzTVlkVPT4X0nFLDw8s72bpEiYJqOqNO4uTIUQ0Uj+zd2AFm64DQCuj5wZfxRmfzzdvlhwz7Jny+fXNq8ijG82Lx6Gae5S38cTsDrAtYP9fMKTPeSeBs2Lof6ugavT4W1g60wj2mOx4kwnZ0+a/4vBY9tYFNgxWDfwR6EncutHUSKgE2Ys1XGz9oiscN6MKu5wz/4TnBv15EkmYKhRc32oXvGtatVFkJWx1gkzZRVTqgh5/vgZQFT0doCuxiWAFsOuxG2MUu16a5/38IKw+4zBUwH71fBBsPWwqJhx2DpsGWwB2BLTQGbgMfvI13A0jBE1PX5eUYI9Qd3dHB+y6eHjiFwMiXV2K1bU48lHE2WmHLFZUinWnIdUlaVRCYXFhLIiYCXBUxD5EbD+ppwRpqPY7PAehl/z4INhw0zBaw/HgfBbs5ybBX8PQ/WyHxdBbEH7G+RLmCaamjo+yvkzZtbY0GrYmAhgcAIaCLhHzGsqMOLKzDMGAXx0ryLQxD0Ub1s8cAuxqM9QcDLAjYQNaxDiEPNmtbelHYdtJflK63xZBRMhxBjYT4BewjPdaiwIqwC7FPY87C2MB2GvMi8QFc8Pga7LLfWFAlDiLe9u0w27DkhCx/vxX2kPPHVYe+bXIt1ZCpkuhWPzptdgh9Ft2OejDt628vdbVengOUsYPlRmXNhQ2A7sgiYCtm9MJ0TS4LNgT0JOx6AgN2FY9UkJiamTXx8vNvazu/+6lxGtxfmyf0968kjfRq69n3QcecR2HMsWd5bvEM+weLoE8jy0bJGGSPg4xKkrSrIDTedV2Fh9sjLAna+IUTd/yMOlmjWSWU8HoENgNWDXQK71fzfU3jUAI4PYZ4bQnzhh03yRmycLHisFzc/DPMH2Cu3O4UgD01V9Q56ZTsOJ0lVhN7finky3XBTQ/JZvEnAywKms8MaxNEbthumQRw6r7Uhh6YQi9d9Q4hl8Vx7XV1gZ2AzYS/BNNgjaxDHq3hNoxFzLG4eQtT1PZr3sEX10jJ5iHZIWUjAPgKa6WXupgPG8OJi7HhQvHABY7cDXRxdM7qEfTfmlR1JwMsCphWiwRgapKERie/AxsCegWmo/PQsNRaLv30Cpv/SAA4N/NAQeRWoEebxOg82BaZh9Bp9eL95TI4NwM0C9h3mKO75aJW8M6St9GpUyZGNnE5FJoENe44bQvbN2j2SBmG7qHElY3ixA7PhR2aFZ/OuvC5gjqhoNwvYTW8vkR2HkmT+iJ5cu+OI1uQ9Jw5gAf0HS+LlQ5juUdYEiYOHdq0tlzarKoUL6lQ2S6QSoIA5oGbdKmC/HUyUXv/5SYb1aSD39arvAJJ0wcsEUpA0eNrq3UavbNuBRKkYVcSYJ9MNN8uW0GWcLJFGgALmgBp1q4CN+XYjFp/ukEUIna9YivnsHNCU6IKO1yPs/qctBw0hW7D1kLGty9Wtq8vt2NZFF9qzRA4BCpgD6tKNAqa/di8cO8fYJuP1m3RJHAsJOI/AFmy2qZGLX6JndibtrPRoWMGYJ+tSrzx3jXZedQXsEQUsYGTWn+BGAZu2OkEe/mytfDS0g3TGlwELCTiZgO4Srhttvr84Xg7heaPKUUaPbEDLquihaQwXixsJUMAcUGtuFLCBbyySw6fOyJxHunODQge0IbrgH4HTaekyfc0eY3hx076TUr5kYfl7j3pyE7Z2oZD5x9BJR1HAHFAbbhOwTftOSL+XF8gobJlyZ7c6DiBIF0ggMAI6T7Y47rC8FrtNFm47LFWwMPrB3vWNjTYLMcNHYDDz8GgKWB7C993abQL29Nfr5VNsgbFkZG8px+guB7QguhAKgUXbDskLP26W1TuPSW3sGP3wxQ3ksmZVOLIQCtQwnUsBCxPo3G7jJgHTlD4dnp1j7Nn00vUtHUCPLpBA6AS0Rzbn1wPyIoRMhxZ1jmwY8nr2blyRwR6h47XtChQw29D6f2E3Cdiny3bK41/+IlPv7ihta5Xz/03ySBJwAQFNVTUD2WXGQ8g052KrmDIyvG9DRNsyUMmJ1UcBc0CtuEnALn/1Z9GJ8B8e6sZfpg5oO3TBHgKa4/OLlQnyCnYZ33s8BZG20UaPrFWMpkFlcQoBCpgDasItArYu4ZgM+O9C+eeAJkaGAxYSiHQCut5Rw+9fn7fNiLrVofNHkXmmUeVSkf7WXfH+KGAOqCa3CNjjX6yTrxGCvHRUbylVlFtYOKDp0IUwEUjE3O+7CL2fNP83STyTJle0qCoPXdRAaiHogyXvCFDA8o7973d2g4CdSEmVDmPmyAB8cJ8b2NwB1OgCCYSfwLGkMzIRIvbuwu2Sln5OrsVWLg/0rocwfN18giXcBChg4Saezf3cIGDvL94hT3+9Qabf11maVy/jAGp0gQTyjoBmwH8Nw4ofI6gJX6Jyy4U1sSC6rkSXLJJ3TnnwzhQwB1S60wVMQ4x14bJuTfHN/bqHJwsJkIAS2HUkyQj0+BK7RRdDSqo7utYxtnLhEHt42gcFLDycc72L0wVsxY4jMvDNxTLu6mbGFu4sJEACfyaw7cBJeWnWVvkWIfhliheSu7vXlVs71pJi2DGaxT4CFDD72Pp9ZacL2MOfrZHZG/fLkid6S4kiBf1+XzyQBLxGYP3u48Zi6NjNB6UC9iN7oFc9ub5dDDfWtKkhUMBsAhvIZZ0sYEcQOqzbptzQroY8c0XTQN4WjyUBzxJYtv2IvPDDJlm+46hUL1tMHkbE4pWtqnHXcotbBAXMYqDBXM7JAvYWIq7GfPerzHyoK9e+BFO5PMezBHwba2qPbP3uE8Zmmo8iz2K/ppWZBMCiVkEBswhkKJdxqoBpWp3e43+SaCTsnfr3TqG8RZ5LAp4loEI2c/0+Y2gx7uApaVattAxDeqpu9bmpZqiNggIWKkELzneqgC1Elu6b3l6KpL0t5KpW1S14p7wECXiXQBrSU32FRAAvzdoiu48lS/va5Yw8i+2YUzToRkEBCxqddSc6VcDu+WilLMKeSbptCjf7s66+eSVvE9Bcop9hO6IJc7YZu0P3bFgB6akaSlP0zFgCI0ABC4yXLUc7UcAOnEyRTmPnyhDkPHzysgtsed+8KAl4mUASUlK9tyhe3vwpTo4np8ql2INM9yLTuTIW/whQwPzjZOtRThQwzTLwwg+bZc6j3aVuBX6gbG0AvLinCah4TV7wm7yNXIuaPHgwsnqM6NeIS1b8aBUUMD8g2X2I0wQsHcEb3Z6fJzWji8vHd15o99vn9UmABEBAhxMnIKvHB0vipVqZYvLcNc2xjQv3IcutcVDAHPDRcZqAzdt0QG6bslxeG9RaLm1exQGE6AIJeIeAZr4ZPnWdbD90Sm5E5psn+jeSKO7+kG0DoIA54HPhNAEb+t5yWbPruCx6vBczCDigfdAF7xHQocTxiFZ8G0OLlUsVlbHojXVvUMF7IM7zjilgDmgSThIwDe/t+txcI7P28L6NHECHLpCAdwms2nlUhv9vrbF+7Lq21WXUpRdI6WLci8/XIihgDvhsOEnAxmOx5asI4Jg/vKfUKFfcAXToAgl4m4D2xjTj/UREK2p+xbFIqt2rUSVvQzHfPQXMAc3AKQKWioWWncfNlSZVS8m7t7V3ABm6QAIk4COwLuEYemPrZPP+k3I18io+ffkFyHxf2NOAKGAOqH6nCNjM9Xvl7g9Xydu3tJWLLuAvPAc0DbpAAn8ioIug/zt3m7weGyflkOJtzJVNpU+Typ6lRAFzQNU7RcAGT14qcQcSZcFjvZg12wHtgi6QQE4EdNsWjVT8de8JGdCiqowe0MQQNK8VrwtYP1T4KzDdde5t2LgcGsA1eH0qrB1sBawW7FfYZvP4JXi823wei0eNPU82/+6DxwO5NSwnCNgOhOz2eDFWHkEmgAd61/fa54DvlwRcR+BM2ll5Az2xV+duNTbR1O2O+iObh5eKlwVMRWsL7GJYAmw57EbYxiwNIAp/fwvTnzf3ZRKwGXie3QZZKmDDzOP8aktOELCx2DJFMwFo6HwlhO2ykAAJuIOA9sKGT11rbNmi6aj+eUUTKV+yiDucD9FLLwtYR7AbDetrMhxpPo7NwvRl/D0LNjyTMNXC84gRMB1X74i8h+2RFfvNwW1CbFI8nQRIINwENABrEvbue2X2VilZtKAxpHg5khDgCz7croT1fl4WsIEgrUOIQ03ig/HYAaa9LF9pjSejYDqEGJtFwDbgb+3BnYA9CVtgnqTHRcPSYV/A/g07l1ut5nUP7Os1u+XBT9fI+7e3l25cLBnWDyBvRgJWEtiCCEWdG1u765j0QSDWv69qKhWjIndEhQKWs4DlR8OaCxsC25FFwLR/rhluD8O0y/IVrIkpZtXwuBumQ48qYB/C3s+mkd6F19QkJiamTXx8vJXtOKBrXTdxsew7niKxw3pI/vyR/YstIDA8mARcSED3HZuM6YD/IJNHsUIF0Bu7QK5sWS0ie2NeFrDzDSHq5jxxsESzDWus6hHYAJgGcmQusfgju3mvIXi9LSxzr+4vH4m87IFtxS+2i1+aL49f0kju7l7XhR9XukwCJJAdgW2IKB6BubFVO49J70YV5VksgI60+W0vC1hBVLoOAfaGaY9JgzgGwXRoMLuSWaQ0KZmKmQ4T1oHp8GEzmA4nloEdgmm+l09gs2Fv5vYRy0sBGz19g3y0NN7YtDLaIxO//LojAa8Q0J0l3l24XV5Ehp1CBfLLU9jb79o21SOmN+ZlAdM23B+mQRoakfgObAzsGZj2sKZnaeSZBUznxPS4VNhZ2D9g38BKwOab4qXXVPF6BKZCl2PJKwFLPpMu7Z+djR1hK8qEG1t55TPN90kCniOgme0fw9zYMmS616TAmo6qKrZscXvxuoA5ov7ySsA+X7ELQwzr5LO7LpQOdTTuhIUESCBSCZxFb0z3Ghv3/SYjUcGoSxvLDe1quLo3RgFzQGvNKwG74rWFcup0msx6uJurG7EDqpAukIBrCOw8nCSPfbFOFv92WLpgw0ztjbk1cTcFzAHNLi8ETFPRXPbqz/IPJAS9rXNtB1CgCyRAAuEioL2xj5ftFE1goGVk/8ZyU4cY1/2QpYCFq8U4bA5s5Je/yLTVCbJ05EVSGmloWEiABLxHIOFokuh3wYKth2RIp1ryNII83LSUhgLmgDYb7h7YyZRU6fDsHCPtzAvXtnAAAbpAAiSQVwS0N/asmUruUmTvGH9dCylSUGPQnF8oYA6oo3ALmE7kPvXVevnq3s7SsoZG/bOQAAl4ncCk+XEQsk3SqW60TERKuaiizh+ZoYA5oNWGU8DOnTsn/Sf8LJpwY8b9XVw35u2A6qILJBCxBL5clWBEJjeoFCVTbm/n+DRUFDAHNMVwCtiqnUfl6tcXyRjkSLupQ00HvHu6QAIk4CQCsZsPyN+xsW35qMLIj9pBapfX5a3OLBQwB9RLOAXs0c/Xiu68vHTURVKyiCYjYSEBEiCBPxNYg2TAt09ZLpoZ9d3b2knz6s6caqCAOaDlhkvAjiWdMYI3BiKVzJirNPMVCwmQAAlkT+C3g4kyePIyOYrvDZ0T61pfM+g5q9+wXkcAAB4bSURBVFDAHFAf4RIwzVD9rxkb5bsHusoFVUs54J3TBRIgAScT2H8iRW59Z5nEQcxeRMTyFchq76RCAXNAbYRDwDR4o/f4n6R0sUIy7Z7ODnjXdIEESMANBI4np8pd76+QpduPyJNIPzW0q+Yvd0ahgDmgHsIhYIvjDsuNby0xfkXpECILCZAACfhLICU1XR7+bI18v36f/K17HXm8XyNHRDBTwPytQRuPC4eA3ffxKpm/5aAsQ/BGUWxyx0ICJEACgRDQrVn+MX29fLhkp1zdupo8d01zY4uWvCwUsLykb97bbgE7ePK0dBo3RwZfiFQxyH3IQgIkQALBENCpiFfnbpPx2O25R8MK8vpNraV44byLZqaABVOLFp9jt4C9HrtNnp+5WWY/0l3qVSxpsfe8HAmQgNcIfIJEwKOm/SLNEF7/7pB2Uq5E4TxBQAHLE+x/vqmdAqZ5zrq9ME+qly0mn97V0QHvli6QAAlEAoEfNuyTBz5ZLdXw3fL+7e3xHVM87G+LAhZ25H+9oZ0Cpqvqh7y7XF7FjsuXt6jqgHdLF0iABCKFwHLs8HwHFjzrvPp7ELHGVcK7PIcC5oCWZKeA3Ynw11XxR2XxyN5SuGDeTrg6ADVdIAESsJjA5n0njbVip86kyVu3tJULw7i7OwXM4soM5nJ2Cdje48nS5bl5cle3OvIYwl5ZSIAESMAOAruPJcstk5fKrqPJMuGGltKvaRU7bvOXa1LAwoI595vYJWAvz94iL8/eKvOH95SY6PCPTzsALV0gARIIE4Gjp87I7e8tl7XIo/jMFU3l5gvtTxZOAQtT5eZ2GzsELC39rNH7alA5yphgZSEBEiABuwkkn0mXe7HmdO6mA/Jg7/ry8MUNbL0lBcxWvP5d3A4B+xERQnd9sNJIwtm3SWX/HOFRJEACJBAigVT8eH78i1/kC+wtpj+euzWwLwkwBSzEyrLidDsETCdVN+07IQsf6yUF83i1vBWMeA0SIAH3EDidli69XvzJWB82/b7OtqWdooA5oE1YLWA7DydJ9xfnyQO97O/COwAfXSABEnAggakrE2TY/9Ya2Tr6N7MnqIMC5oCKt1rAnpu5SSb+FCcLH+8lVUoXc8A7pAskQAJeI6C5E/u9PF/SkX7qx4e62TISRAFzQKuyUsDOpJ2VjmPnSOuaZY01GSwkQAIkkFcEZiJ7/d0frkTi32ZyfbsYy92ggFmONPALWilg36zdI/cjvcsUbAPeo2HFwJ3hGSRAAiRgEQFN/nvl64vkADbGnDesh+U7YVDALKqoUC5jpYDdMGmxJGAxoa79yp8/Xyhu8VwSIAESCJnAom2HZNDbS23ZDJMCFnL1hH4BqwRs24FEuQi7Lo/o11Du6VEvdMd4BRIgARKwgMDNELCNe0/I/BE9pWQR67ZfoYBZUDmhXsIqAXvmm43ywZIdsujx3lIhqkiobvF8EiABErCEgGbnuOK1hfLQRfVh1i1upoBZUj2hXcQKAdMtvzs8O0e61i8v/x3UOjSHeDYJkAAJWEzgbiRW+BnDiT8N7yHRJa35gU0Bs7iSgrmcFQL2BdZcPIo1F5/ceaF0rBsdjBs8hwRIgARsI7DtwEnp89J8ua1zbXnqMmt2hqeA2VZd/l/YCgG7+vWFciw5VeZg12VUqv8355EkQAIkECYCurB5OiKlYxGRWLVM6GtUvS5g/VBvr8AKwN6GjcuhHq/B61Nh7WArYLVgv8I2m8cvwePd5vM2eJwC09r5DvYg7Fxu7SNUAdu454T0n7DAliifMLVr3oYESMADBBKOJhkppq5qVU2eG9g85HfsZQFT0doCuxiWAFsOuxG2MQvVKPz9Laww7L5MAjYDz5tmUwPL8NoDsKWmgE3A4/d2CtiTX/0in69IkGVP9JYyxdVNFhIgARJwJoF/frNB3lu0Q2ZhtKhuhZIhOellAesIcqNhfU2CI83HsVmIvoy/Z8GGw4adR8A04dc8mG/3SBXEHrC/2SVgiafTpMOY2dK3aWUZf13LkBoDTyYBEiABuwkcSjwt3Z6fJz2RaOE15EkMpXhZwAYCnA4hDjUBDsZjB5j2snxF6Y6C6RBibBYB24C/tQd3AvYkbAFMczfpMORF5gW64vEx2GW5VVIoQ4gfL90pT0zD1gV/7yRtkD6KhQRIgAScTmD8j5tlwtxtMuP+LtK0Wumg3aWA5Sxg+UF1LmwIbEcWAdMYUO37HobpnNdXsCYwXeDgr4DdhWPVJCYmpk18fHxQlXjtm4vkRHKazHyoK4M3giLIk0iABMJN4ERKqtELa169TEgb7npZwM43hKg/C+JgiWbl6q6QR2ADYBrIkbnE4g8dXtwNC9sQou6502z0j3Jrx5oy6lJrwlLD3ZB5PxIgAW8SmDQ/Tp79bpN8fW9naVGjTFAQvCxgms9EhwB7m8KjQRyDYDo0mF3xiZSKl24xqmKWDqsD0+HDZuZrWYM4XsXrGo2YYwl2CHH1zqNyFRJlvoFx5Ets2m8nqFbFk0iABEjgPAR8ORI/HtpBOtUrHxQvLwuYAusP0yANjUh8BzYG9gxMRWp6FqKZBUznxPS4VNhZ2D9g35jH6zzYFJiG0Wv04f0wW8Lo3/l5uzwzY6MsGdlbKpcuGlQD4EkkQAIkkBcEPl+xS0ZMXWdk5qgZXSIoF7wuYEFBs/qkYHtg477fJCpiW8ZcYrVLvB4JkAAJ2ErgpVlbEMixVTb/6xIpXFBDDgIvFLDAmVl+RkgCthAC9m8KmOWVwguSAAnYSuDRz9ciN+JBWfqEL2g78NtRwAJnZvkZFDDLkfKCJEACDiegexempp8zlgAFWyhgwZKz8LxgBez5mZtk4vzfjB5YAW5eaWGN8FIkQAJ2E+j6/FxpVaOsTLixVdC3ooAFjc66E4MVsC9XJcgj6IbrGrBGlUtZ5xCvRAIkQAI2Ekg/e04aPvm93NmtjjzWz5e4KPAbUsACZ2b5GcEK2I5Dp6THi7Hy7FXNZFCHGMv94gVJgARIwA4Ce44lS6dxc+XfVzaVmy+sGfQtKGBBo7PuxGAF7Ny5c9L6X7Okd+NK8uK1LaxziFciARIgARsJLN9xRK59c7FMua2d9EBOxGALBSxYchaeF6yAqQv3f7JaYjcfkMVYC1ayiK7NZiEBEiABZxP4avVueeizNTL7kW5Sr6Ju+BFcoYAFx83Ss0IRsLW7jskVry2UUf0bG+PJLCRAAiTgdAKvzdsmL/ywWTY+01eKFw7+hzcFzAE1HYqAqfs3Tloi2zEfNn9Ez6AXBDoAA10gARLwCIGRX/4iP2zYJ6ue0u0Ygy8UsODZWXZmqAK2YOtBGTx5mdzTo66MCCGix7I3xAuRAAmQQC4EBk9eKseTU2X6fV1C4kQBCwmfNSeHKmDqxcgv18kny3bJO0PaSq9GlaxxjFchARIgARsI9PpPrDSsFCVv3Ky7UQVfKGDBs7PsTCsELCU1Xa5GZvrdCE/V7QlqlQ8uOaZlb4oXIgESIIFsCGj0dOOnZ8rNHWrKk5eFtg0UBcwBTcwKAdO3oevCrnx9oRTIl08m3dIGOzSXc8C7owskQAIkkEFAxWs8kvi+it2Yn7ummVzfLrT1qxQwB7QsqwRM30rcwUS5fcpy2Xs8RV4Y2FyuaFnNAe+QLpAACXidQFr6WXnyq/Xy6fJdckO7GsYi5oIFgstC72NJAXNAq7JSwPTtHDl1Ru7+YKUsw2LB7g0qyPC+DaVpNd1gmoUESIAEwk9Apzh0zeqsjfvl/l715JGLGwjEJ2RHKGAhIwz9AlYLmHp0Oi1dpizcIa/HxhnRPpe3qCrD+zSUmOjioTvMK5AACZCAnwSOJ6XK0PeXy4r4ozL68iZya6dafp55/sMoYOdnZPsRdgiYz2kVr7eQsX4yNr6cjAjFTnWD27rbdgi8AQmQQMQR2IepjFvfWWasUx1/fQu5rHlVS98jBcxSnMFdzE4B83l0LOmMlCleODgHeRYJkAAJBEhg24FEQ7z0R/SkwW2kUz3rfzxTwAKsFDsOD4eA2eE3r0kCJEAC2RFYvfOoEUym+xROua29bXPwFDAHtD8KmAMqgS6QAAlYQmAekovf8+EqqRBVRD64o73UjLZvTSoFzJIqC+0iFLDQ+PFsEiABZxDQTXZHTF0nDStHGT0vFTE7CwXMTrp+XjuSBOwsdlrNj2EDFhIgAW8RmDQ/Tp79bhMCxaJlIua8oooWsh0ABcx2xOe/QaQImIpX+2fnSPWyxaQZ1p0ZVr201K9YMuQFi+enyCNIgATygoB+7sd+/6u8tWC7XNqsihFtWKRggbC4QgELC+bcbxIpApZ8Jh1pYjbLuoTjsmHPCUk8nWa88SIF80vjKqWkOcRMF1SrsFHUHNDw6AIJhEggFdk1dMhwGjaovKVjTfkH1nlp4Ea4CgUsXKRzuU+kCFjmt6i/ynYcPiW/7D4uv0DQ9HE97BRETkvRQqaoQcwMUYO41avAnpoDmiNdIIHzEtDP93Jk+pkwd6ss3HZYhvVpIPf2rGdJdo3z3jzTARSwQGjZdGwkClh2qLTRb1dRMwVNRW1DFlG7AD21jKHHMsZj3QolOPxoU7vjZUkgUAK/Ideq9ra+XLXb2PmieOEC8jQyyt/QPrSkvIH64TueAhYsOQvP84qA5SRqv2GVvvbOdOhRHzfs+XNPrUnVjGFH7anpMGRd9NTCOUxhYVXzUiTgOgKaW3XGuj3yBURr7a5joiOEnbEo+ZrW1aVPk0oQsYJ59p4oYHmG/o8be1nAssOfrj21Q4nm8OMJPB4z5tSSzOHHYoUKyAVVzZ6aOfxIUXNAQ6YLEUNAc6nO/fWAfIne1rxNByQNn8lGCI2/unU1Y4eLSqWKOuK9UsAcUA0UsPNXgoqaDl8Yc2rmfNr63SckGVmutaioNYGo+Xpp2mOrw57a+cHyCBIwCeheXSuRcFdFa8baPXIiJc1Yx3Vly6pyVavqxo9GpxUKmANqhAIWXCX4RE2HHn2ipj01n6jp+LxP1FTQdPixdnkOPwZHm2dFKoF4zEvrnNZXa3ZL/OEk48dgXwwNXoUhws5Y0xXqnl12cqOA2UnXz2tTwPwE5cdhKmq6qeefAkUwp5aSetY4W0WtKebUMiIfM4YhKWp+gOUhEUVAk3vPWLfXCMjQXpduzaULkLWn1a9pZSlZJO/mtQIBTQELhJZNx1LAbAJrXlZ3go07mBHSnxEsckw27j3xu6iVMHpqGaLWqEqU1ELutprYN60ihk+s2HTP3nfHq5OAfwTOpJ0VzVM4Db2tuZjXOoPPha7HvBo9rStbVZUqpYv5dyEHHeV1AeuHungFpsvG34aNy6FursHrU2HtYCsyHaOxoxtho2Evmq/vwONJmE7O6EretuerbwrY+QhZ/38VtW1mT80QNdhGDD+exofcV3StWky54rAMQcswPMdr1ZBtpFCI26Fb/654RRL4MwGd11qNyEEVLY0kPIrNJcuXLCwDWlQzAjJ0iN3NP9K8LGAqWltgF8MSYMthN5qClLkVROGPb2G6mdZ9WQRMRe0cbGkWAVPROuTvh4kC5i8pe49TUUs4mizxR5JkJ+YFdmA+QOcEdh45BUv6vcemXmgYf9UyRSFmJYxdrlXUfAKnolfCJUMw9hLl1fOCgEYQxh04JXN+3W8EZOhmkpoNp0+TynJ1q2rStX55R89rBcLMywLWEaBGw/qawEaaj2OzAHwZf8+CDYcNyyRgV+J5Z9gpWCIFLJBm575j9ZfsgZOnDUHTSW/j0RQ6fTyGX7aZS/mSRTIETXtwZu9Ne3K18LxcicKu/tXrvtqLTI81jZOK05b9J2GJsmUfHg+cNNqmzgVr6VC7nLFeq1+zylIqDMl1w03aywI2ELB1CHGoCX2w1jdMe1m+0hpPRsF0CDE2k4CVNEVNe28qapkFbDv+PgrTFjQRNul8lcoe2PkIOf//uuvsTkPUTHEzRU57bnuxrXrmohPk2ktTgcvovf0xRKnzEFyk7fz6DqeHOjKgP5K2mkK1GY/6XMUrNT1DqHRxsQ5vN6hUEhYl9WFtapaVamXcN68VCFsKWM4Clh8g58KGwHZkETCd71oG+xw2OouAVcPfu2EVTZG7H4/zs6mUu/CamsTExLSJj48PpN54rIsIpGCtWsLRjOHI33twRu8tSXbhdd+XkL6lQgXySY2yPmHTx4w5NxW7GngsihBnlsgkoKnWtD0YvSlDrDJ6VhpVqwEYvqI/flSoVKR8gqUL+b3YNrwsYOcbQiyNBhNnipO2ncqwI7ABsJdgNcwGVQaP2rqehv03y0drtHm+L8Aj208ee2CR+YXkz7vSoZ69x5PN3luSkQDZ6MkZc29Jv2f012tpqHNlZEDw9d70F/fvz9GLK13c/v2X/HlPPCZ3AjocrXkEt0KctDelQqXPt2L4z7fcQ6+gvaf6Zo9Ke1UqVvUQNZiXqZucVrdeFjBd6KBBHL1h2mPSII5BsA05VFIsXs88B+Y7LLNI6d7Z2nPTKER9rnNnz8Bm5lbxFDCnfSyc4Y9+0Wkeuoy5tj/33lTgDiWe/pOjZSBgGXNuGb22iqWKYFPBgljTU8hY16PPM/6G4TFcezY5g2b4vdD623/itCFSGcN/GT0qfe7blUG9qoR6yhCoDJHSnpWGt4djQ8jwU7H2jl4WMCXZH6ZBGjou8w5sjCk4Gio/PQtqfwSsDs6ZZp6nAvmxec1ca40CZm2j9srVTmG/Ne2l+SIlNWrSNw+3G9GU5jx+jjgKIzItyhSz34UNYldKRc4UOv0S1ed6XGbx04AAnxB6ZTmBzkWlYChP973TYWE1zfqivSZ91Ne1N515CPAk0jH5ioav+4RKe1YNDaGKYs85hA+s1wUsBHTWnUoBs44lr5RBQCPUNDJSNxVNxJfoyZRUOWk+19cy/61fsr7jTuA447lxTNrv0Wy5cdUQbRU6n8DlJHSZ/28Io4pnJmEMJmWRzhvp2r0/xMQnKqawqNggrPwP0THFxhSgDCHKEKUMMfqrMPleyzxXmRuPsugJ++anDJEye1cafcpiLQEKmLU8g7oaBSwobDzJZgI6BKZf7idPQ9QMEfxD2FQAfxdHU+x8wqjH+gTQd9z5eoP6VjQHn9HbM3t8vmHOP0TlrJw2ez1/iM0fwQ2B4NBgGQ16UNP7qunC9T+9hgwtvtcy/v/n44rp/wviNeO4jGM1+W0FLKFw8+LgQDjm9bEUsLyuAdyfAuaASqALthFQIVTBUQH8QwRNUfSJnyF6GaKoWdB9IqjiZQgMRELn7DJEI7/xqK8X+V2AMsQn83E+UfKJj+//en4wvT3bAPHCQROggAWNzroTKWDWseSVSIAEvEOAAuaAuqaAOaAS6AIJkIDrCFDAHFBlFDAHVAJdIAEScB0BCpgDqowC5oBKoAskQAKuI0ABc0CVUcAcUAl0gQRIwHUEKGAOqDIKmAMqgS6QAAm4jgAFzAFVRgFzQCXQBRIgAdcRoIA5oMooYA6oBLpAAiTgOgIUMGdU2UG4Ycd+KuVxXb93hs4jFG7wUdG4wU/6aF0jJkt3sKwJNytY56p9V8JmEiwBEtCkxG0DPCfch7vBR2XiBj/po3Wtlyy9xdK6d5vDlShggSPmhzBwZjmdQZbWsHQDR/5gsaaufVdxS51b+66zXI0CFjheNzQcN/jIL7TA256bfwiwvq2rb7ewtPYdZ3M1CljgiO/CKZMCPy2sZ7jBRwXiBj/po3VNlyy9xdK6d8shRNtZ8gYkQAIkQAJhJMAeWBhh81YkQAIkQALWEfC6gPUDyldgBWBvw8ZlQdsNf78Maw67ATbV/H9PPL6U6dhG5v+/wuMUWHfYcfP/Q/C4JsQqC9ZPve3zsEth+WGzYA/CzsHamL4Ww+N3mV4P1lU7fIyFM1VgyaZTffB4IFgHcV4oPj5nctTb/wv2melHbTx+CouGrYQNhp0JwUc91Q4/p+C6VrbL8/n4CO43FJYG0yUtt8N8y1puxfMnTUb/xuN75nOr26Q/LIPxM9ztMjcfZ+JNXgj7GXZZpnZnR7sMsVlbf7qXBUxFawvsYlgCbDnsRtjGTJhr4Xkp2DDYdJhPwDLXRDn8sQ1WHZYEmwKbkcOxwdRgKH52wg1fgKkQa9FGPhIWC1sGewC2FKYCNgH2fTAO4hy7fFQ/lb0GpYRaQvFRfwA8BLsEVsTk1xuPJ2Cfw76EqYi9CVsLeyMEZ+3ycwp8sqpd+uOj/sjTtqWfib/DesCuh+nnxRdkpD+kVPRVuI7CrGyTWgV2+RmLa4ezXebEUt+jtsPisL/BMguY1e0yhCZt36leFrCOwDoa1tfEq1/sWsZmg3sKXsvpw68T0/rL9ibzvNyODaYmQ/FTz/0vrAtM63o+THsIx2DzYNpz1KLC3QOmH4Jgih0+/gpHYmFWfVGE4uNw+FEUpj0vLZNhP8D+B9PeRWWY9jSy3iPcLHPyU7/MpsCsErBAWCqDVjBth52zaWsTzXrWurayTep97fDzkzxsl1lZ+tpXD/Nz4hMw/axb3S6Dacu2n+NlARsIujoMosMcWvSLvQPsvmyo5/bhn4vjx5tfDnqqHqsfnNOwObDHzefBVmaofr5ovketa/0SGQXThdg6XHqR6VRXPD4Gy/wLLhB/7fBR7x8L06G5dNgXMB1u0l/twZRQfNShy3/AtLeuv3a1p/AaTIe+lsDqmQ7VwKP2YpsG46B5jh1+/gfXngKzql0G4qO+LW13+8z60x8k+mNA61LLUzAdIo6FWdkm9dp2+KmfJ/U1L9plVpa+ZtYDT5Sr7/OrGU+sbpchNGn7TqWAhSZgOj+zDlYVlmpWk76mH9bCMA23j4M9E0IVBvIhnIL7ZP6VrV+sOsenQzdadA5sBEy/MKz8srDDxwXwsRpsNywKpgL2Iez9IFmG4qPeUoX/Wpj+stV5OB1yVn+s/qKww0+dx7WyXQbi4824t/4o1FEK/VHnVAHz108VsLxql1l99H0UephcKWBBfjm48bRAhhem4A1mN/yiARFNYDqMmF3J2rCC4RSKn1mHlJ6GAymwD2BWDtfY4aMGn2QuQ/CH9hyz6yH7wzUUH7Ne/2O8oOKlvS2rh2rs8FPnODOXUNulvz5qD/9VmIqXL/gm63C1E4YQA/FThxDzol1m56PPj6z1ySFEf74RXH5MQfivQRw6Caq/8vUX9SDYhmze1xS8lp2A6a9vnTtTMfAV/aW7F6aNSCMVVTB0GDHYEoqf2vO6E6ZDpeqPRizpr/FvYFknzPWLJusXnb8+2+GjikMZmCZOLgTTL47ZMA2UCKaE4qMGA6gvh2EakaoC1hKm8146D6a9Q18Qh/bIXw/GQfMcu/y0sl3646POe2nQk7a9rZl4aBCHBm60Nl9bhUcN4jgCs7JN6uXt8FMDd8LdLnNi6cPaA08yDyHq61a3yxCatH2nenkIUan2h+kXun5BvQMbA9PhPo2S0qjDdrBpsLIwFSIdGtQel5ZasIUwnfc4m6mKdE5MMzkrWw2fvxuWGGIVBuunvi/9MtUoRJ07UgHTkFwt2puZAtMwehWL+81jgnXVah9LwBENOlHx0veh4qW+63xYsCVYH3XORr9otegXmNapb2lEHTxX8dIv5tUwHebRobJQih1+Wt0uz+ej1lczmP6Y07ITNsB8riH1T5jP9TP3rvnc6japl7Xaz7xol7mx1KF2DcYqCdMfWHfANMDIjnYZSpu25VyvC5gtUHlREiABEiAB+wlQwOxnzDuQAAmQAAnYQIACZgNUXpIESIAESMB+AhQw+xnzDiRAAiRAAjYQoIDZAJWXJAESIAESsJ8ABcx+xrwDCZAACZCADQQoYDZA5SVJgARIgATsJ0ABs58x70ACJEACJGADAQqYDVB5SRIgARIgAfsJUMDsZ8w7kAAJkAAJ2ECAAmYDVF6SBEiABEjAfgIUMPsZ8w4kQAIkQAI2EKCA2QCVlyQBEiABErCfAAXMfsa8AwmQAAmQgA0EKGA2QOUlSYAESIAE7CdAAbOfMe9AAiRAAiRgAwEKmA1QeUkSIAESIAH7CVDA7GfMO5AACZAACdhAgAJmA1RekgRIgARIwH4CFDD7GfMOJEACJEACNhCggNkAlZckARIgARKwnwAFzH7GvAMJkAAJkIANBChgNkDlJUmABEiABOwnQAGznzHvQAIkQAIkYAMBCpgNUHlJEiABEiAB+wlQwOxnzDuQAAmQAAnYQIACZgNUXpIESIAESMB+AhQw+xnzDiRAAiRAAjYQoIDZAJWXJAESIAESsJ8ABcx+xrwDCZAACZCADQQoYDZA5SVJgARIgATsJ/B/S5AGaz0LCRwAAAAASUVORK5CYII=\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b5ee178100>]"
+      ]
+     },
+     "execution_count": 146,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "outer_2_x_smooth = np.concatenate((outer_2_x[1:17], cx1[5:14], cx2[13:21]))\n",
+    "outer_2_y_smooth = np.concatenate((outer_2_y[1:17], cy1[5:14], cy2[13:21]))\n",
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.set_aspect('equal')\n",
+    "ax.plot(outer_2_x_smooth, outer_2_y_smooth)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 147,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 11.72 um\n"
+     ]
+    },
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "C:\\Users\\engel\\AppData\\Local\\Temp/ipykernel_21064/2861829821.py:25: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).\n",
+      "  fig,ax = plt.subplots(1,1)\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbAAAAEgCAYAAADVKCZpAAAgAElEQVR4Xu3dB5htZXU+8M/E2AkqdpGYogYVg9xYkBhRwYgKNmyoEU0sQDAWQEBNjLGgWIIFFXsPBnsBFPQaaxIwoImREBSwIRY09vwt/+93v/sx5w4z957dzuxzZq3n2c/MnXv2Pvu8e5/9fmutd611uRQWCAQCgUAgEAjMIQKXm8NzjlMOBAKBQCAQCARSEFjcBIFAIBAIBAJziUAQ2FxetjjpQCAQCAQCgSCwuAcCgUAgEAgE5hKBILC5vGxx0oFAIBAIBAJBYHEPBAKBQCAQCMwlAkFgc3nZ4qQDgUAgEAgEgsDiHggEAoFAIBCYSwSCwObyssVJBwKBQCAQCASBxT0QCAQCgUAgMJcIBIHN5WWLkw4EAoFAIBAIAot7IBAIBAKBQGAuEQgCm8vLFicdCAQCgUAgEAQW90AgEAgEAoHAXCIQBDaXly1OOhAIBAKBQCAILO6BQCAQCAQCgblEIAhsLi9bnHQgEAgEAoFAEFjcA4FAIBAIBAJziUAQ2FxetjjpQCAQCAQCgSCwuAcCgUAgEAgE5hKBILC5vGxx0oFAIBAIBAJBYHEPBAKBQCAQCMwlAkFgc3nZ4qQDgUAgEAgEgsDiHggEAoFAIBCYSwSCwObyssVJBwKBQCAQCASBxT0QCAQCgUAgMJcIBIHN5WWLkw4EAoFAIBAIAot7IBAIBAKBQGAuEQgCm8vLFicdCAQCgUAgEAQW90AgEAgEAoHAXCIQBDaXly1OOhAIBAKBQCAILO6BQCAQCAQCgblEIAhsLi9bnHQgEAgEAoFAEFjcA4FAIBAIBAJzicDCEtgOO+zw6xvf+MZzeVHipAOBQCAQWCsEzjzzzO/k9772Wr1/k/ddWALbsGHDr88444wmWMRrA4FAIBBY9whc7nKXOzOD8MfzAEQQ2DxcpTjHQCAQCARmhEAQ2IyA3trbhAc2gosQpxAIBAJzh0AQ2AguWRDYCC5CnEIgEAjMHQJBYCO4ZEFgI7gIcQqBQCAwdwgEgY3gkgWBjeAixCkEAoHA3CEQBDaCSxYENoKLEKcQCAQCc4dAENgILlkQ2Aguwno6hZ/9LKXvfz8lP//f/0vp//6v/Kxb/fdXvpLSZz+b0j3ukdLVr57Sb/1WSle4QvlZt/rvq1wlpe23L/8fFgjMCIEgsBkBvbW3CQIbwUWY11P4yU9S+sY3Uvr615d+fvvbhaBW2n7wg5R+/vPhPi0iQ3bIzM/l2/Wul9INbpDSDW9Yfl7/+kF6w12NhT9yENgILnEQ2AguwhhP4de/Tum7303p3HNT+u//Tul//ielr31tS7JCUsuNF3SNa6xMIJVQEMyVr7yyN1W9qx/9qLzXH/xBSr/xGyt7adVr+/GPU0KOqxFn/fsvfnHZ8712bqSA0Cqp3ehGKd30pind5CZl2267MV6dOKcRIBAENoKLEAQ2gouwlqfAi/qv/1oiqkpYfl5yydKZ/eZvFo9l0oOpD/3Jn7/92yldboR1/wj5O7nzz3KPcfm/L754y6vBa6uENvnT78g2bN0iEAQ2gksfBDaCizCrU+BR/fu/L21nnZXSOeek9KtfLZ3BTjsVz8MDevKBrV/menhgI/Tzzite5ySZ+/ckuV3xiind8pYp3frWKe26a/l5q1uldLWrzepqxvusMQJBYGt8Abx9ENgILsIQp/C976X06U+n9G//lhKiQlxf/erSO+24Y3no1gcvshKuE9oLWxkBYUqk9qUvpXT22UsLAVgzniccK6nd7nYp3fa2KcnNhS0cAkFgI7ikQWAjuAh9nMKFF6b0yU+m9IlPlO0//3PpoXqzmy2RVX24XutafbxrHENoUm5w0rP1u+vBeK0bNqR0xzum9Cd/ktIee6S0ww6B2wIgEAQ2gosYBDaCi9D0FDw0eQEf//gSadUHJtHBHe6w9MD849ws+6pXbfoO8fquCAjXKgOwmLCw4AkrEWA3v3m5PrY99ywCkrC5QyAIbASXLAhsBBdhmlP44Q9T+uhHUzr55JROOSWlCy4oexEZ1IehFb48DMFF2LgQUPeGxCqhfepTKf3v/5Zz3GWXlPbZJ6W73714aFHPNq5rt8rZBIGN4DIFgY3gIqx0CrwsYUCEZbOKJxsnEthrr/LAu+tdU/q93xun6m8AWH38889P6W1vS+n3fz+lBzwgJVqKubRf/jKlL3whpY98ZMvry4N2XV1fG1l/2CgRCAIbwWUJAhvBRain4KEmLPhP/5TSBz5QciuTK3QPNOHBka7Qkctpp6X06EendKc7pfSa1xRdyLSGs+khNOH48pcvu4mSgqjai16U0hOfOO3RR/66SQ/bgqWGhIUb733vlB74wJT+6I/WzWJl5Fdr0+kFgY3gKgWBrfFF8EQWVnrHO1J65zuLVJtqTTiphpUoBkdo3/xmSh/7WIls2hDPpB19dErPfvZlT5yYjzDyi18soj5kZV+b5/ikqTPmZNYNPO9/f0oXXZTS856X0hFHbB0YpKhKAMzqmCc3Hp1/T/6UpiIwpLvAF2tiTlptnlDxhz6U0saN5QMob+B2IjOh4jHW260JYGvzpkFga4P7Fu8aBLYGF8HDSEiwkta3vlVI6173Kg8o/f9GKL3WJcqzFGn56RnLNNjgcd3lLoUMTjyxpHue9rSU/v7vy7MXR7/3vSmdfnqJnFXzMZHT7/5uSkrN/Kybv1/+8ilJF3mWg0slwJWulNK++6b08pcXkZ9qgUqIvEDkxpNT0tWlcxVvUjRvzU0B9rvfXQCwUsDI5PqIzP0ihxZkNvPLFAQ2c8gv+4ZBYDO8CJSDr31tSm95S3nKqrm65z3LgwhpzUgteOqpKdm87e1vv/rnpzHwvEQ6COs//qO81mnSjSCsO9+5PD9FvY45JqV/+ZeUfud3Cnnd5z4pHX98SiecULpCIR77ITsejjpgArzJZy+PCPl5Txty4hUhqj/7s5Qe/ODC8yKsjmsdUOuw1WAjPQ1DrnnNcp5yZEjQRttSf68/a+cqJMsj5H19+MPlc555Zkq77TbD+2Oat7KKqGRmJeHD/+EfpnTggSk94hFF1BM2EwSCwGYC89bfJAhs4IugT5+cloQQV8KTE2kdcED5OSPS4hm9730pvfKVJU/FPOQ1neBBVeO1ON23v70QCELhJRE4IivkQ5nvwS9N42PhZB2ZEMhTn1qepUKDe++dkjCjSOgjH3lZjgaNY3gt4vjMZwoh1TCiBhc8IBviq00unvvclIQnRVYd13khRF2stmZIigfnM09u2jzSy9RWiTjA5XnBC0bu2IinIjMLIsBhaOz+l39ZQtDutbDBEAgCGwza6Q8cBDY9VlO/Ug6DG+HJjgk8kYV8PFj+/M9Tuu51pz5U1xfKL7361Sm9/vUpiVQStT30oSXdhjh4G4hGlIoogsckR8WTuf/9C8fuvvuSbgQJCOchQukZH9Wz8nGPKwRVn5lHHVU8MqSGgDgKCMv7OA+E530mjV7hT/+0vF551Gq11sKSf/M3ZU9hR4SDhHl4iNU56P/rXKnXtXTkAao8QOTVvFa4kqJRvus2tynkrGsU54bHiWCdM28UweEIhK5f8XWus9QesraJ9LNuehbPLLKnJdjrXpfSG95Q8qh6VlpJPOpR5QOG9Y5AEFjvkDY/YBBYc8xW3cMT+k1vSukVryiJHk86cbq/+ItS3zOjp5mQG29LiI1K28McET3mMYVQHvawcnqPf3zxMhAcj8ZDGmkdemjxeOrpIgHeEfGE/BbywcE+FsUhElluHvxPeUpKn/98Oa5zAAdSsq+HvPAhQvV8RV7b8qDqeyBNYk0bEkaIyLCOGEM0CBPZCCEiN89z5+m9KCP95MEtL5kT9pSr83cNTOyDqJARYkSKLrMcG57gYdr8bbkhVOTqs/rpc59xRrkOsINJ74ahP/jB4hqL6wKCi3rIISWmGzWCvUEeBNYblO0PFATWHrtL9/QEe9nLilviySae5SklYTPtU7mH07AI99x64xtTkipBDpw+i3Ddi449NiXhN6dkoS60h8Re+tLihb34xYVIkI8HrXwW4uJMEkNQ78tDcSL322+0av5OSHKUkaL8Ho9SDkyKCQGttv5AqJxsxF4JTYrT7/Wn3xEeb44RtQjLDmrcTjeDFQp1C3fzCU8oN0Q0He4MfRBYZwi7HyAIrAOG3AtxN5W1lv33vW9KT3pSqdWakbdlwf2udxWnj0fCS5AG4RkhG6t84cLDDishNKI1hMUb8ODlJfDYahhRbqg2iEBYHuCcR7kvYb1FH4+FvBE5bxMW1aQqq1LSwgCh8cqEIeFYB0kv/4nYeIh1UypA5ELBObO+ydxGbuULX1hUMVzSxz42pb/6q+KGhrVCIAisFWz97hQE1hBPTysSPg8DaghxMStaK9secw3eRo2T0BTykZOaNHwpxcajQkz+H2lJe1QhmjDhX/91yecoGzruuEJCk/aqV6X01rcWD0t4z3F4YbUOam47XTS8rCu9HOkQl/BskRny4cioL68N6Fd7G+SP3BCfxYJNKFIok1csPLkmpj+jRZdVjdWNKIFFlybPYY0QCAJrBNcwLw4CmxJXjEK7TT2g6MiTSLLISlZGv0cj50Y8VS2IFzU4r96PsB6yopwjg5e/kuOqORUP2Gc9q0SOLLb97vUhSuvvIvF8eVdVuYjoERbikmZa7oATCdLzIEIDoqWmeL/CuRYccpNClcQk6pUHyY9NfnxMbEUj5mz6tXjyM59ZVCxhUyEQBDYVTFu8KOu9Ur7rUv6KpHznpazzWtFyKj6dlLesq0o5m7G6BYFt4yJUjwtxSQZhk6c/PaWHPKT3JJBV/TOeUZSAyMrCmJRdaJAibuedU3rOc1L6278tkR/PH12GPCw9EL3O80i9q79RBjoeuXzY2iFAps/jco0oHa13EBTRCfFJzZPVM0RqxohZnFCAGis22AQWJyD+LEHqBnRD/d3frWEbkrW7Tk3fOQisGWJIKwt8U063J03y8tM05adoyuv1LSw/+lKWIaW8Fkw5yB0E1gzmza9GXKp4EZe8gcSF3ykYenZlrOKF8hze6pxT5xnCs0JIPCj1VRw+WhEyeM8ceXghrn/8x5KGU+MkL6OeVY/AldSBrbCInTohIKeIuMjzEZLrRwQz2adX/Z1QJef+X/+1TGIRAq69H4lLEBlS81NIuNcB2U7SikhoHKntv39Z/dziFp0++yLvHATW7OrmWz/lOyrl1Pwmy5U2myxnQbawf8j/yuLpdHjecvYkCKwZzPnVJGK8LC4NV0dbCRWzAzTRJXNHNsKB1M7/kK+eUNLBB5ccV23H5KFWH1xPfnJ5wEnFqfMSsiLYII+3gB5hF6rGl2DRdkBQyhpstQWX6+yay0sqWyC3nzSRPWpQIWPXmypUXo4JPxLYuCd0NFEaoIaus1lByZG5EZ2ASAOXH4OGbYFAEFizGyIviZIQYk4Bb7KH5y3fvpu8rGoa3+S1ehJC3Ji3ILAmGMvSYwfdDSQmuECSR54WPZvVNnGGtBrhhHosZTrmIFr84k7kJS0hHIjgdKaoORfiAFJvPQHtp+lt2HwgUPv0KiK3Vqo1ZJx8bbmQEe+M8MNtWDehRypJRFa3z32uhCIZzpE77cXciG7Kl7ykKHwoFnlkk21benmj+T1IEFiza7ctAlMWmWNe6cC8nb8NAstFSsmWk8c7bbigDkdsdj6L82orTXI+4RPuDOLiFg3gyljgCg8KBZJRIykPHSIAJIWQ1BPxvoSaJk3eXT6FfkROJWpS5/8WJAZBQrqM8bLlOq2jeGzLTeQaqSEy94uAgFyafZncpzKJXk3xmtg211EizngBVdhx88U4lYY32rZCiDn7kVSu5KfxJtPVM2dlU462rx5GXNciDnkuySN6dayBMczoGGjEu3otoUHPBFJqLZFqVymemP57PKv3vKeEhsLWJwJuS2ko4UICD9vk7xZB6s04Rn4ShyifwCuDmeScqncuo1AAz0zccx1beGDNLr7OnEQcuVNcyiX2m0Qc+ZGX8rp9RduY/xohxNUwllzg+hBoKHryhVSA3MF8x62K1VFNmoeMt9KoQ96CvL12Ofd/woTUhUpx1JtGbWmHi7BOdhVKrOPj3HNqzIh23Ht+DlJHj1m5eYfn9DrF0IMeVNSL63RqdBBY8y9bbm6TiDQoEnPnzpT9+ZQff5s8rNz9bgsLAlsJX+FCnWYNk5I4Ejq0fO1QeON7TTyhe4PDiESqa2ZCQRp0yHdw9CgKa/cGf5NyEzp0Ck5pgKhl87ss9hg1ApSJggS8MmHFmhetJ61sgtrxbncrIWkdRHo1N7VIxfOfX5hSWJF3ts7CikFgvd5V7Q62rkKIZPHiLJJJktLYhO68g0mga3v45jeXg0jAUwb6jnu4EFjo2s7r0rCDUZSRxTsdAg7Jdw+asEBgGgQsmCgX//mfUzrooHIv4Q5F0hZDcmn+T09HRsJPTKjpxnKl4zTvt+pr5M41CdY8WPRCN/w1azHS6ZO02jkIrBVs/e60LghMjQv3R7GVNgcUEj3E7zVo5V1RhBFmiKjopIC01GaJSgod8qw8aCgLLVyNI+H8efAoNl7P7Zr6vZvXz9EoF488stQDWighJ1yikUYNHxL8ENS6FwlFRAeMqpHqdd/20mcam5pH5ka3ahMPV4Hfc63kGK9sENgIrsrCE5hiKVJ4nbkpC33BeojTacrhISChboIK0tprr/KgMHiZ9NnDhKrMd1tui3Rev0FhQw5gNAQfwRdgzk+B1yVk7R5EagqcBRl4XJOlFe5JPEOzROWoMoTXTziki1TnRRSlCYUSxuTyGUC34EXQQWAj+PIsLIFpVIeweFsqRn2htDHowTwIcCIFoblbHhp4Ub0nJ09IkVkh87jkvIzOUGjswTKzLuQ9fNY4xHwgIMiAnHRuOfPMElJU2GzYqHuPQMh9x2ESwtbAmR7D2B2lXebAuTeFJlunsqrIw+rMCakbE/lofcBxYx8ENoLrs5AEZsyJghgxFF8gzNJDMbJkOVKy4jVe5J/+qaxyqcEUHz88l5YbvzSpAFMPShrfw9uP4G6JU5gHBLSg0jiYqEgEgInoCW/rsWhTpqGtpzys1yrxoG9CZqIKVI6txYVYUTzTF0TMElvOcAr5rK5RENiskN7K+ywUgVkBWoJSRKn29M3END2YPqfyDFo/+W6aGcWz0otQ/loHhY0bg6h6gDoO0SMClIpaUcnTEncIfQtOMDkwbaikhRXH69VoMcaoaN3jrc13UdTDlwUrcg/1zVogCwIbwcVcGALzraSI8EUxnVGcT3FMD0bNZTqvVamkeVUTKkgW7idr9mDoVeHVw3nHIQKB5Qi4V+VikRlS09ZKoEKKuJqySB6ZES+djTv4wAcWdhQJqZLJzgde+wMEga39Ncg1vBt+fYai3nm2yZChZJQ6rw51XZNQ+P6JglhQEmLUWmedEvCk/9ecIMYozfMNtH7PXSsr0nsCEB09hL+FF3vtdC82SYZrUblAIcUgsBF8b+aewBRgUU30HDJ0aQyGlC/AhXIFtSG38heFywZPCrlEDdcIbuQ4hVYIEHpYgFVTIO1vlIn3ulePs1qXhxR9cTp2vmn1gXvcKQisRzDbHmpuCcxyUUhCMbLYumKXFiHDn/60qLTI3kU36ndKqMVhTUKWQ5ArYIqSjQSzcqXiMsYkLBCYRwRwirZTQuPyXb5SQuEWa8LjWlSZW0ZUiNR6aU8lZHG/+5VWVG94Q0ksz6kFgY3gws0lgWl/offSiSeWoheJqZYxD7VcmudW+9jHipTYd8sIMM0F/NQ4FcFRIJLNE1jFiKQR3MBxCp0QIKmX30VeOsIYhorYEBkNlAAHAZOwIlW8BVtnIvvOdwqJcf10tPbF6nzQTjC02jkIrBVs/e40dwRmaahqmFukyEpj0ZY3vxIxXeFNQBaal2vWJcOXlORY+YqaGm15iKnkCoTykVjUcvV7H8bR1g4Brc8Q1yc/WaIRiIyQg4lQKA055piUhM79v8bTnRvZWBH68smLqT/Ra61zNfVsMQwCmy3eK77bXBGYpJPAvB5ObnzVly3N4g9p8baEBSkLjTQhO+bMCZ/svHNRACMwiiyOntVqWCCwaAjwwKje6Z84SDiFHsqQTWZqggoVEXtfP4s8PXwr0bXCg6vngOaNiVGSPpo5NicWBDaCCzU3BIZxqCVUBGt/QV3R0qw4hUR07RZCQViS1/hQyJCpg9HLUI0MjQjPq4cOVC3POHYLBGaDAHUtD+u440pYUfcYHaIQlUCHdod6e/LIhBYFQ0QBa4641VmKVUoJYEuFlpU1Wx1sdjsFgc0O61XfaS4ITFYZeWkNoLdhhxtchxtCDXUv6mDksXwZrTyR2eQgSUKOBe2CM4I7L05hzAhQ4PpeWNAJI+rGptWUzaIO0Qk1vuhFpTCaFkOOrHVe2Fhp0RXV1RLRxjSM3ILARnCBRk9ghmbRrOt7c/rpnVrSaAVFVWWRJ9clhOjLR4mFuIQSwwKBQGAJAW2laKX0BxBKZ7wxRGb6gqiEmZaiFbRVQo+6ty0f6joVpjphK66UYEZimHLEFgQ2goszagIzZ4haSTIK60y2126BnQ5TL33plg13zbM8+ujijXWISrY4m9glEJgvBHhlyEzEj7ipFj3jHKIn44JMHVdiwhtT5dLYNCWwshTXt2D13R+pBYGN4MKMlsC0vdCQl2adFyZh1cEIMMTyjSqiImTCiabValKPK8MCgUBgOgR0hlJ6KWpBci9fpmm1cKPfpbSIQloZuW9tf4PEOiXYWp3BVDsFgU0F07AvGiWBUSOJT4hViPWRAnYwuS2yX8opvFjzWhT4L3hB+QJGK6gOAMeu6xYBoo5LLklJNzpBErPGlKMQf3TKH2vYeJe7lAJMOXAL2ZFZENgILsjoCExLd0xTyavj2Fhxefc+GfBZZy1xIafOrCSlKCecMIILEacQCMwZAtSIwvI8LukqJSZyYJ2k9ZMY6DKsHQ41lbrPDuKtIaANAhsC1YbHHBWBGV6kUtJsB1WVHcOGoJBcNhG5Fij7GyIzZcX34dOfjsnIDW+ZeHkgsAkBEf6TTiq9BJRonnZacZiE5Kl6CYdb9hhYQlg4cY89en0m9HX5gsD6QrLDcUZDYDLE7nzFjVZbDWc5aLFGietLo6aLORRZrxaJ/o+J3QsnKvr3t9ZD+zpgHrsGAouAAOGT9aZNEwBRDv0FyOvVWipXkXvuHP2jDrnb3YrKSpxyJNNhg8BGcBePgsBodbGKXjUKlkmaGhgpfI006hyvfsWq0Kwjct5XvaoUI/v3XnsVlZS3udnNGrxJvDQQCAQug4Bhy5pbCxvqL6AptnIVAg4tDuXHNNqg9O2UE9M5W15ctwFSyE4H6+dCBoH1g2Ono6w5gYk5yHmJ5Z18clEfNbSXvSylQw8toUKqqNphQ5NezXqJNDS/1i6K5yXUMVJhU8NPHi8PBNYeAcSlLsxEI/qrWo6iU4fvpRoyIXtkV6Mjrc6aa/fEJ5aDahXSOT7Z6iwu3SkIrBt+vey95gSmm7xyf3f3AQc0/kxku3/wB6XOWaRBFHL77YvyXq0KdaH2at/9bkq3vnWZ30U6HxYIBAL9ISCvrK2UPolGs2i9VvlFR3v/Vp+sMXCnfqJPfnJp/0FBoi5mDS0IbA3Br2+9pgQmzsAtetrTSkO1FubLorarjkHR8maXXcq4E0bEweOqikNNesMCgUCgfwQsEqkQBVKE6jlJtSPHl75UIoDqlA87rDQCbvVdJHmU6PallsRew/qXILD+76HGR1wzAjv77OIuURjpb9gipm1SOc9LOFC9oySyXJgBfOq7wgKBQGC2COAXOWcqRLlp+bGnP720NhQtsdjUrUOYUUePVi0PMeVuuxUXT/upHtTKbVAKAmuDWs/7rAmBaYFh5YSBjDy+7nVbfarahNdCjOLpX/+19DQk7e0waaXVucROgUAgsISAkSzatB1/fBF1GApL1KF0xfdT/WUlO/mzxubLTv5YuxNQb83YgsBmDPhKbzdzAqNtV6r/7neXuF/LyXiEi3JZiKu2gao1XxT5nZLFI7gucQqBwCIgICeGyHhlvvqIi3eGvBCXihnk5rt7tas1/MRVvWUl+5SnNNy5+8uDwLpj2PkIMyewyjLPf37Rurc0YQmz8EQQiDMYDQh5PMVhWCAQCIwHAYtKeS9T0GsaC5kRH5s/xhq3dMOI5rhQZmk3ZSjmDC0IrDnYuflRyqnRlIfdpzwfNeWlxxaWI8wp3xYpO+3p23nLComUi6tWt5kSmCpiVY3aV9PetpTBXnxxiZ3f856lJIS5l41FEVuvAo7m8MYegUAgMCQCSj3lwBDZt/MTSg77vPPKO/LMKplNfQ4SbYrQFHfq5KOj8IwsCKwZ0EgrM0DKT/+U1zMpVzcl0ePcxOVSy43DUq6PT7nFZsrC1bRn3rL2Z3WbGYFZdulrRoak78z1r9/s00+8WixdWMJhqA5Zlczra/joR7c+dOwYCAQCAyFAxCFzcPnLp7T77qVbnAqaH/+45Kw1G9huuxZvblCZQjM1YiT2M7IgsGZA50uenpG3XPW7yfJ6ZZPlR/mKJrCWS3xTlvmtbjMjMEHwxz2uLL1I51uahdaOO5YvgELlavqyke8KVXRsXt/yzGK3QCAQ2BoC+EUtMkNiUuF/93eljrOzKTSzepVUm9FgvyCwZldt//xyIUQhQpYrLlLW3KUsGl/RkNdFecuZotVtJgT29a+XgpDb3Kb0MmsZOvQpxMwp73WWQVrMSo4WRMsaX4iwQCAQGB8C1q/WsUq4CK/wjdIX+gs57VZ1YfVjUjZ7xmgHIhzT6WDTYRcENh1O9VVNCCxP49lEbNmvTrlX02UsO+vJlnvm7rThAoHpoUxy6t73LnetGHWrwo+lk1OAr86rKg15ZHhR2xq9DmcYAh8KsThuILCQCBBcSVf5/pqMflFeXiOvN72pVNWQ172UDeQAACAASURBVHeamPL+96e0334pPfOZhREHtiCwZgBPG0LMNfAp3x6byCvLHbZug3tgFBViBSqLtYGZ0vCecPa3vlXERTppCDsYVc7LMiJI6Yd71ehyPdj0PQwLBAKB8SLwhCeUDh0eC/tbkmczZPYRjyitpvQ06NS9nirRw0CuvSbIB4IjCKwZsPnxvUnEodttjsltEnFoHpgH5lxq8l55HbMp1HjuNIcflMDEB3beuWRmjWzFQFMaZWy9we1S87N4kPpeoaTeh8KI7lmtFMMCgUBg3Ah4JOy5Z5nJR3tRO0ERZKlJJvQw07Z1s20SZUk1TcEpRga0ILDm4OaZp0kalCIx63dSrqxI2QdJmR1S1qWnHKdLuRNgyuWDm+zCvGWfenUblMBqvI+6ggvVwKiT9PnVIkr9iIJIN7laETla4W4hQ503pNUaF0E2OJd4aSAQCPSHgKiK761BFLro1KyCAcy1lEteu3W2QV9VCXGCDu3qBrIgsIGAbXLYwQhMmygrIW68jhsNhRsSvnqlmSeEwIQJdd/Q65AXJm5ukaWYOfJeTa54vDYQWHsELD51gvLdNTmiRvsMYEZiJkogMcPZG1ttkir60+LZM+37BYFNi9SArxuMwDCLRGrLVZCZlobjiYlz4IxgEDKccbH9gMjHoQOB9Y2AMGING4q41JSBKMtd7lIEHb7zxiE1ttpmqkX0Z9r3CgKbFqkBXzcIgUlQKbF3F7aIQ//gB0UNy+uy6fer+XQINQa8EeLQgcAaIHBhTnLIY+vNq7WUOjFeGcdpn33KaCRphDpxfepTlGzj1nHlyOoHaPYbBDb11RjuhYMQ2BFHpPTCF6b0hS8sDQRq8BGEFKzM/NR1Smz8Jjcpw/CMZwgLBAKBxUFAKYyU1fOel9LNbpbSP/5jSiIwH/hAURZrWnDKKSld5SoNPzNl18NyRZEDGkbWswWB9Qxom8P1TmDiz1rB3+teraWBbmZ5LzkvAkZJX+FEUYFDDmnzKWOfQCAQGDsCPC0DMY370uv70EOL3F7X+rvdrcjtr3jFBp9C+zpqL17Yv+iw168FgfWLZ6uj9U5gBgBhmc9+tkiNWpiWiXp0Ut6zn+TOjsIK+h8eeWSLA8YugUAgMBcIyD4Yr8L7IrFX8EzYIbyoPkxKvZEnVnNhCKznFlNBYCO4pXolMNXHt7hFYRtB7YbKQ3AIXetl+NjHpvTiFxeALKQMbJYPU8gcFggEAouLgMfI296WkkzEN75RipzVhmkYJLCj4cbUpsWUiNB97pPSm9889W7TvDAIbBqUBn5NrwSmXZSkVYdkFa9La6jJSn1toiiRpNWMJA8LBAKBxURAAwP9TvU2VfAsL+Z7L0/GEFvjCc5ikZowGhTYcvr7SmgHgY3gHuyVwPQ85OO7URoFq5eAeMMbSgjB6DDCDVZFHRK5xB1hgUAgsHgInHPOlt2fDKr1PDB5SUrBBPYWQZ2U6oF77pEYBDaCe7A3Ajv//FI6f/TRpbq4pR17bAkd8PzrbCAtFIWyJXej40ZLYGO3QGDkCMg6SJuLvvC4RFsIuUT+JtvKtfoYVr6aiYtDNmhpt7X3CgJrdSX63ak3AiMb0loakXVoKf2Sl6T013+duxDnlmbXvnaZtMwT09SDBxYWCAQCi4mAPoi+80KEr351UR/f734lqKPzDkV8a6vNVUkd1af2YEFgPYDY9RC9EZilE7WFMvoOViciaPQpDu7mvcMdUnrNa0pvxLBAIBBYXARMU3/LW8o6WLoKqRFu6MiBewxebmXGPmNH+Qk9WnuwILAeQOx6iF4ITM5rp50a69z1Q3vqU0uoUKeNgw8use7rXKd4YXoe7rtv6YmmYr9xNX5XcGL/QCAQmCkC5+YZGloYmhlWpzdLJxB2eTaQ1OvS08ruf/+yIjZMsIfOHEFgra5Cvzv1QmA17idZetObTn2C17pWyWtJ0uo2X0eGCRWIgwtb88gajhKb+v3jhYFAIDA+BNR8yXtZ4NaO9IZhKuMShSEobGW1M4cW+MI6HS0IrCOAfezeC4Hx62ndtY5qYLyv5zynJGotjuRYv/zllH72s9L5hZz2MXluNBltDwumBmcWLw0EAoG1QuDredqhNoY4Ri/e+t0n5lIbqkdCq5pkTVaFEcnqPVQ6WhBYRwD72L0zgVFb6POk87xRyQ1MohZBiUB+5Sul07wb1NTWsEAgEFi/CLzylSkddFBJMVRRs1CiXok77lg6Q7Va1BprYbCgB04rTf7SNQkCG8H92ZnATjyxjEQm3qjjVaf8XIoSH/rQEiqw4jIfiCPn/goLBAKB9YsA9bHFLfHWZAqhRgGFEf1/Y3vFK0qyXYdwEzM6WBBYB/D62rUzgXGXTjghJe75b/1Wo9PSnFOHF9MOiDhq2zIEJpEbFggEAusXgV/8IqUDDij5cLxjyC1i0yv1858v9ckigo3s7LNT2nXXInW0eu5gQWAdwOtr184EZmS3rht0rg2tdp6qknmxb+EBE8Gf9rSGB4uXBwKBwMIhoDeq/LjmvrVDHSUiDjJa6bWvbfiRf/nL0mxVg0Ur5g4WBNYBvL527URg1Ba07Urmjzmm8SkRAwkbTraIkrhV+2GIZVggEAgEAh4zymk++tHiOCl01jNB7wQlNnvs0RCju961KMeEfjpYEFgH8PratROBkQm6e0xdFgtsaKSxGzak9J73pKSNIiMOOuywokbU+ywsEAgEAgF1yPe8Zwn0aGn4xCcujfryHGmUvaAM0SWYKqTRbJYtr0MQ2Ajuy04E9qIXpUTbetFFrbo8y3WZvjI5MFV44Ja37NTQfgSoxikEAoFA3wj8/OdFuKGtFN2YBa4ZgTrX6dwxtYlHcumwIelzSwsCawlcn7t1IjAVxxJY2mS0MH01b3zjLdtESdxaTcXsrxaAxi6BwIIhQNwsOuO5oDuP0KEozVFHFUEHO/DAlF7/+gYfvI541+rDQVtaEFhL4PrcrROBSWDp7GzaXAurk5bVefDqq9GESKtZXYUFAoHA+kXgAQ9I6SMfKX1ROU4yFe94R0pf+lIp5TKr8o/+qGGDecxnrAV3rk7NbQFxEFgL0PrepROB3ehGpbMzeVBLEwYgodcsmrm3TF9GaNSIYYFAILB+Edh998I1SKx2rDOtXaFzJ5O7UBX9rne1PkwQWGvo+tuxNYEZ2HOlKxW9e8MOHJNn72ZUnGh0OEGjZK0blqhRuCAsEAgE1i8ChBueDVWVXNWHLXVjS0DqyCGU2EGJGAQ2gvuyNYHx33XaVIjxqEe1/iR1iF0lrDo81SRWpRphgUAgsH4RQFhSVfokWC9bN1MuExCa2n6FK7TERjcOXYR0E29pQWAtgetzt9YEJu+lJF41srqKKU3eS9Nepn0Ur8u8H4ejyjftQMW9SvtddpnyoPGyQCAQWEgElNjc974pfeITpWaUfehDRVIvcqNTRysjoz/yyC1Hvzc8UBBYQ8CGeHlrAjPvQCl8wxEqJiufd175JDvsUAhLKYZ5P2oL2c1vXlorduy1OQRcccxAIBCYIQIcJO2i/uZvUnrGM8oby5NrYyiFpVt9K3v72wv7qdvxwGlhQWDNQbt73uW4vGWZQ8ptLtPy9hdZv5dylUTKTnbiG+ehJOn8rb1NawLTTZOrJEBtoNeUVklJ7dchh5ThlcYjIC+iDTkwqsQ6B2jKw8bLAoFAYEERoED89rdLk+/agf6II0po0d+3377FB6+j3884o8QkW1gQWDPQkFaO+qa985ZHiqbso6TcVCVN9m7Pgd10q7xlZkm51C9l53sTia1qrQmsSoK+853iSk1p9b7RPkr8eu/8aeRThQpajUeY8n3jZYFAIDCfCNSpFZMND2obusm/Nfp0p56a0t2zP9BhuGUQWCPEUxaUpmfkLc8p3mS5lG+TTVZL5auy6TU5MJdygVbKLTKSfs2bS/4u+4atCcyMg8MPbxxD1tdMSID3zomrPGhsgmmrYYFAIBAITCKg/65JTbwto5e22y4lfzOG8G53K7mwxvaxj5USID/33LPx7nYIAmsG2/755UKIeeD2Jnt43m6Xt7+aOAx5hNfw0Jhsk9dkN2lla01gRikr1tLfpaEU6IEPLA08RB+Z+0coWnFi4/EIzTCMVwcCgcAcImCApZowjTNq7fEjH1kiN2bqNuqF6PPXPq48MSzYwoLAmoHWJ4EZBbdpHNxOO+204QI9nZqajKr6r1/9qrHaouZPq/dexyMYz0M+HxYIBAKBwHIEKN9FbQi8ND+o8wQ//OGSimhkcl+UY3IaZNAtLAisGWjjCiEefXRKxx5bCjMampoOnpZZmEYiMIfTOqqDR9/wLOLlgUAgME8IEHpRHu60UxF+mRV2rWuVetHjj2/4SdTp6EF10kll4FgLCwJrBpqcFhGHoqs8+nGTiEMVRA6+XWpZ15dUT1URx/3y7zlgt7q1DiGaaaDjrruosf9evHY9gIUNmfowXehJ6g1N1U4qLBAIBAKBSQSINswDo0JUyoV7lOJ8LSdNGonAMKCYpKKyffZpBXIQWHPYsl4vZfHoJhn96/L27LxlJknZH07vy1uuVU+5QCvdOm/fyxslYp6sNQCBvfzlOfuW028tR6kYhnrooYXArKqYJp0PyppJI8T3FzANCwQCgUAgI0DsTC5vrSyU+IpXLIk3pB6EE/fbrwFUH/xgCR0istuRCTS3ILDmmPW+R2sPrCayFGfsvHPj8+J9meMz2fOQssjfKI4kZ8MCgUAgEJBqOC5Xv1IdUhzqyCHnpQ3dbW9bBGE6+khNTG2Giok9nntuSrortLAgsBag9b1LawKTOf2zrOif7PHS8OQsfH760xIyrAXOBx1UbtLvZf/RpJawQCAQWL8I1FSVsSrEXvRm+u9e85opaQT+P/9TJPVmhCnrmtpIGc1s8qC5xjWm3m3yhUFgrWDrd6fWBOYuqq6SiXMtTB/gv8xFAZNh6BrjpjRy+LBAIBBYvwiI0BheSSov3S5Pfvvbd2ghVaE0RYNqjAitUfJs6VoEgY3gvmxNYGZ4G+bVoRu9EjJjeQg2Pve5lK561bLCMqWZqog3FhYIBALrFwG1XoI9Xydby1YJrXOzbw8XyXbJtZYWBNYSuD53a01gYn8YZ7LLZosTO/30Es+mLNIfWCiRElGfRM0+wgKBQGD9ImAC85ezDA1hMXxz3euWsptOA2+1s//qV5cO3ALiILAWoPW9S2sCcyI3vWmppbCS6WC1qYfm9i99aekN3HHad4eziV0DgUBgLAhIs6v/0omjGuGGobcf/WiHsxTmucMdUtJosaUFgbUErs/dOhHY/XKZmeZktgb2gQ+USd7i2ne6U8mlPjsXBCgr44EZl0Dk+GBFAGGBQCCwbhFQL/rDH5Zar2oPz030aMdkMVqZaZg0+R46XLmWFgTWErg+d+tEYMKH3Kcf/aiMS53SquLQGB4qfGEC4UMqI8Rl1o8Ss5gHNiWg8bJAYEER0Df1rLPK9OVq+iG+8Y1L8wMbf/RaxNy4eGzLdwoCa4x8/zt0IrBaeewOE0qc0moTaGTFC3viE/MMmDwE5n25FPtGN5ryIPGyQCAQWHgE5LlEZnSir1ObDFKmgicCa2VGXzz60WWybofBg0FgrdDvd6dOBMZ9IiN8y1tSUg4/panbIIWVQzXQWXhABw43qKLEHXec8kDxskAgEFhoBBQrqxfV5FvdMdNDXC9xz5FWCngr5hNOKLHJVgco5xEENoJbrxOBqaFQAq+i0HjUBqaMTDNoakPCDTfqXnuldIMbpPTxjxelUVggEAisbwTkw3Xn2XXXEqFheiDywkxvp1hubEY8e3YJJXawILAO4PW1aycCcxKyrAZ7/YdRZM1MnktPszoeQWKW6khnl40bS7V9WCAQCKxvBDhMnhPCiIZZWvA+/vHl37rRNzICDqEew3jl7ztYEFgH8PratTOB1cnM2kHf8IaNTos89g//sBQumy/Hmz/ttNJjc5fcU1+NGAcvLBAIBNYvAp/8ZEqcpqpMfl1uY256OxUi76yRceN0DuphblMQWCPkh3lxZwLTyJB/PxmkbnCq1Ifqv1796tJWipHZ3/e+ZeK3NlMxWqUBoPHSQGDBEDAzl7jLYtei9sQTS4kN1TIlcyMzAgMD6oF4xSs22nX5i4PAOsHXz86dCczdJXF11zymTBfehibG/ad/WsaqkMrWvppVKMTL1wstLBAIBNYPAl/5ShF3yYtf5zqlWe9hh6XEGxO5EaVR3KyouZGZ3SRHYZxKRwsC6whgH7t3JjAn8bCHpfSRj6T0zW+2UvVw4owI131DrJshNh2o3WeILeT1fVztOEYgMH4EpBMQl251JrcTePmp9Sr+UXKjV6pcmDz61FYbrdLgm9HS0YLAOgLYx+69EFidrdNqSVQ+RZ35Mxmadr/pVkWhz+sPCwQCgcVGQMd54wU1MTADTCGz4bYKl1/1qjxq3qz5zSZKIxc2tWE9sudWscfLvksQ2NTID/fCXgiMT6+BobvJqOUWppnHhg0pEQnhwZ12KgehQHrJS4oXpkNHWCAQCCwuAkpKtYqSB9dvV1TGiKXvfrdMY1Y76llgVqDUQ6NuPYpPf/KTLQcQdoAyCKwDeH3t2guBORnt5E89tYQRWyZHKfFNWxXzFpGkMHI4KkWlZogsLBAIBBYXAWU0hlTakFMVebUc/L4ElCQ7145q+slP7gXAILBeYOx2kN4IDHkZiXrSSSnd//6tT0ridp99UrrylcvKS7NfubBPfarMBGq04mp9FrFjIBAIzBqBH/yg1HVp7q1Ymek4Tx/WWfVOCXbssSkp97ne9Xr5aEFgvcDY7SC9EZi+LuJ+1Bjvf3+nkxKiJqM/99yiD7nkkiLm4P0jtrBAIBBYPASsfS1WNTQQiWF1XTz5t8afvMdn0+R7B4E1vhL979AbgTk1/V246Fylhr2gxLhPPrl0ntYXeN99y7QDqkQtY3hiVmHhgfV/D8QRA4ExICDfTajBE5PvYr7/Bx9cJrXXvHjjc60saG4hRUhPFgTWE5BdDtMrgZkLprKwRfEWx+3f/70kZ3/xiyLooAfRkePCC1O6yU3K/4UFAoHAYiJgvCCBxmRXukc9qvRA1Daq9eIVaYlFdsjPr4R4ENgI7sNeCcznkYXlRunz0iDep77DzWvKAW/riCNKi0UdqJVt1ALnEUAWpxAIBAIDICDqIkVlIVvNwtWa2OiuVka84QByYEI6PVoQWI9gtj1U7wSmlfyeezauMlS47B6TvCUSMgPI/aYCn0Lf5O8aF2/7WWO/QCAQGC8ChMymVNThlRddVL77tBe6cLSyAw9MydxCMUjV0D1aEFiPYLY9VO8Ehol03hT3o4W9whWmPjW7mraqwt68HySmCt+NzaEzAPqpT41Q4tSAxgsDgTlCQM2XcCHiYlXUYeqJmWCNzUND2yjtOhqOe5rmvYLApkFp4Nf0TmDOVwdeVYjaZzzykY0+gdaK6qH1BuZ9kdQqblZAr8iRF6blYuuEbqOziRcHAoHArBAQeXnlK4toixF1+DdRR4N18NLpemjoEv7lLw8yJTcIbFZ3xlbeZxAC40pRZbgTCTsatpOneuV1EQ1NdqlHYAcdVG5mHan1SwsLBAKBxUBA1MW0ZbMmCbZ4XXoimNLe2Ag2NE/U1sNDZAALAhsA1KaHHITAnAT20chMEzPzUhqanmjG9lDAIiv1IUxUUo2Y3KxC5w410w3PKF4eCAQCfSJAWUi0oWzGLEBRFwEba15deMwClPt67nNbvKtcBBmzBwUlyAAWBDYAqE0PORiBiQVaQqkJO+ecMkq1oSlcNvBZHkxtNIEjE1K4xz3KJOdTTilzw8ICgUBgfhDgFBnN9fOfp3TAASUtoF3ULW5R1ry/93sllU59uN9+DT8XHb4ZhQYMikEOZEFg0wN7zfzS7IekG+ft/Lxl1ybl/hRbWL5iyTASM4xzEC7RjNpnqzYYgXlXXXk10KSJr71htnVCy/5fn+A737lwoG4cfmf+Lh9mBSfJa9hdWCAQCIwfAQRFHGhBakySrvIiK3qeKpdBYmecUepBrX+NG5zapC/kFmjxyRn1phrIgsCmB/b5+aV5hGg6Jm+53UXKlzk9ZdnuefBIylcv5QZMySXPgtSUu1em/Khf3QYlMG8rJmB5ZVVkNkoLu/ji4mWdd14RctSwIWWsgXbbb1+8MT/DAoFAYLwIiOjd+tYp3eEOpfMO2bzfLU5FVTTyeeYzU/rhD8tnwEeN7J3vLN02hA+JOAa0ILDpwc3+R9ozbzkzmXJlRNqYt1z6u1XLYyKTvikIbVUbnMC+9a1CXHvsUe7SluX03/lOCSVo9kudpEZMnbQeabwyPRPF0MMCgUBgnAggI00K9Dq16amrSbdICjLTC5zxvOTBeGdXv3qDzyLnoOO8nTDjwK17gsCmvza8qHop85CBTeHDrV1ag7azo56yM55yMmoNCcxbv+hFpTpZIsss8Jb2s5+ldPjhZXElRn5M9kd5Y097Wkn01j6KLQ8fuwUCgcCACAjEWGhOKotf//qUtItCWJ3TAFXGuHFjYcqBLQhsS4BPy/9cqc9/Lt3dREaThIXAhBFXsuqh5SZMKWeHVrRcMphsuZ5qpw0XiMUNaXSxpEZk9Z//fOdYn6a+EsBWcYZc7r57CS32OOpnSDTi2IHAukPA4pMYkNclNU51yB784JROPz0lgZr6t1bgSFH88R8XifLb397qEE13CgKbHrFpQ4gEHBvz9py85eEE27bBQ4j1FCgtxAoUeJlS19KEF3CgxK6FltWcMOI1s8zlwx9O6Va3anng2C0QCAQGQ6B6WgbV1vpNpEUuTyzYcpB7OV9SRslwLTy+8IUyEXcGFgQ2Pci5G1jKA0cuFXFQJWZp3xamZ1OOJCfDuP5h2kPPjMCckCpFbr4VkqVXQ3vTm0pXGAle4W3dqxU219HiLdNrDc8iXh4IBAJNEZDfIsIiDKzfU+kA3XYIO1rqu8ppOJDwS8cURdPPFAQ2PWI75JfmjpQpT4xM4n1k9FSJ2WdOj8tbXsOkHF1OOaKccmDtUjsw/5Zbw69uMyUw7pPiDncsN0qWtoEpK1MTJmyoUxVHzrBLeVspNvXSdY5Qg8PGSwOBQGBABHTWoRA2WeLlLy9vRB6vTaEGBRamrc2YFC7dYx9bhofN0ILAZgj2am81UwJzEpZh8mFc/tNy2q9B4FtvTveqQ8jRCh9++tOl+S/REWGHhr8PfejgAqQRXLk4hUBgPhCwVvWVt+Ak4mAiJ699banv1PGplVm9yhlc9aopfe5zKV3lKq0O03anILC2yPW438wJzLlr8qtjb4s5CaS4VmxKPPRJI50nbNQ/GHm5j4UjdLJ/0IMat2HsEdk4VCAQCEDghBOKg3RuLujhdemta/6f2X/HH98SIw8C+XR1X2prCDhmbEFgMwZ8pbdbEwJz84kdvOc9pdnhXe/aGAmxdGk0BfePf3xKz8+l3pr8aj2DvKz6zLHzd+HGsEAgEFgbBJZPVdaFQ39TkZRGXTYmT7+W5rSY/t4XCkFgfSHZ4ThrQmDOlxKD/t3YZYktS7OGRnz0lNyP5LjjSnW/LwWprjaM73pXmR2G6NSKvepVKe0gkxgWCAQCgyHgu6fpgNmRVawhfIioFCsLGVpY6rWLg1qZAwm7kMwbVtkgDdHq/VbZKQisTzRbHmvNCMz5iiXIhbnbyexb9oIyBE/HKh3sEZXmoEz5GZUTj+y61y3RhtvcpiVQsVsgEAisioCgCnGxBaX+pML3pkWwG96wdNmQ8xL18339yldaqt1VPOuvKuH9yU+W/NcaWRDYGgE/+bZrSmBORDHX3nuXjQy24eyw+lm++tXy5dCaRnrNANarXa38L4EHL0yZiHh8i+kuI7hScQqBwDgRIC6Wk/bdskC8fm6lgKTUeSnJ8j00bVm91y1vWUiu1YiU72XhNSmyCbean67xVNsgsBHcj2tOYDAw8oAsyfAfwo6W5ovE2/LlILX3hard64U1jCfTxYPYQzla1I21BDp2CwQ2I+A7J+Jh/N9RR6X0939fQoMGUPjOCdtzkjQa4Jkxc8AaN4n3RvvsU6Zb+hLrALzGFgS2xhfA24+CwJyIJRxJkg2ZdbCPf7z0VxOhFCZHVtS2QoqPy1VzRJBITF11WCAQCLRDQL6LIIM8frKNmxl+QoRUh0wPb823q1iQ89TIxCe5cOauaOnhTUdgQWAjuAijITDsorXGBz7QeorzJJw//Wlx5nyx6EUIHZGakQ1PelL5HiA6XTzCAoFAoDkCAiZyzMafPP3pZX8pKvO8apRj8qj6IV7pSg3fB3kZP0GppWs3F28kFgQ2ggsxGgKDhTuc5l1ejKTQXJ+OJmwulKhI/8ILS4qNIkrO7FnPKkrFsEAgEGiGgPpLwimt3V7ykhKOxzWifJoLiH40DhOudApIi/v2hCeU2OSI4v5BYM3umUFePSoC8wl/9KMyqpW0Xp1YD0VcWtl8M09S86XSTJSU15fLyrGXL9kgVyYOGgiMEwFtoIw+UTusmU7VXemIoybTT8TW2SSzjz66VDyTF4+IvHy2ILDOV7j7AUZHYD7SD35QYn5GJGixYRxzSxORFIEwspwiyqG0o3J4I8zDAoFAoBkC0lFvzAOevvjFIpZiWhJadwrRv/vdPZRmcesUi+kL581aqpObfbJmrw4Ca4bXIK8eJYH5pN/Nzff33LNkg5FYy2TVdtsVp468V600ARM5PSPsIL3X0SPIbJDbKw66YAj4OmrVpjVUHYGiN7eeBOq9hA9/21CnLsbboraqhcoDT1Zue6pBYG2R63G/0RKYz4hp6OB18ZUT22+/xp+8LuTsqAMARaLu9UKJivjVTzNfQGRGaq/oOSwQCAQui4BaLsNjtYFCWNaZtTTLoMrWjXm9lSSasKHEtNSBzgMano7UgsBGcGFGTWDwUUziZj7jjNJ+npSwoZH7npTHuVeElwAAGxRJREFUeyIvKimtbYiZdKPBjToG6CJgFp6uNEKMwu73uU90tW8Idbx8gRGoTXhVuVgY6nxDMm8RKITYqTTLl1Ss34G1rFfrMvLZSEFgI7jZR09gMBIDpEjU+NcKTSl/i4QuMQeiQmRWkFaOBE61l/B/5klq/l+3eypF3Wq8Vhh+jdqtjeAOiVNYbwjoMUqcYe2og03taCOqR32IyHTbEEa0puSR+Y60NkyotsuXD4mpfZmDL1wQWOsr3t+Oc0FgPm6PN7mSM19EXhiikmrT1FoYkSE6rXD8v273u+6a0otfXF4XFggsKgKaXSg3sajTBoohJgTlOyO0XgfJKsuibCcS9PrWZnGKJT/84Txv/pjSwqPF4rT1+3fYMQisA3h97To3BOYDT4YZfLNU5jeujFxCzkpTvtgX8OKLy5cTaelsX99O6u3II0sNmfwYIms9AqKvixbHCQR6RkBo/eEPL31DpZ0PP7xI4nlaujedckqp8bKwM7aI2lBKWpqqtbOEJR2kQ3qgZxgaHS4IrBFcw7x4rggMBJOJXp3sfYN23LETOD/+cQm9mx32/e8XIrO6JLn35axdPUQvr3zlourdd99Obxk7BwKjQMDXSbrp0ENLz0Kd3ETrtXsSYucUidjrXmPxRl9hwSePrBl8DS82/jDqPHXe0WlA6PDe9258iLXeIQhsra9Afv+5I7CKmWITbeWNEafQuOMdO6Op/AyRKcTUcFSza14XsYcvMy+MUlFYUfNSkY+wQGBeEfjJT4paXS9DwiU/r3e90hDH2tB3wDw9pSiEGvhGQwBGOm+qcivTx40SxJtpViBGP4cWBDaCiza3BAY7lZSkgopTBOV9KXqIn/sCG4jpC3366SX+L2yix5vOHST4vDP/FxYIzCMC5O/CgDwtQiWelVph+V8iQMpcTXi9pppIhe+FDhxKURqbLxKRxstfXpRT3mSOW+EEgTW+A/rfYa4JDBxifoL3Wm5oziYG0iEvthxho4cUPwuXaAyijY4VqealhvSFBQLzhgDdBEGS+xmHWAMyOimz9Ig2auiwt88m3/WAB6T0iU+UsUni8SMtUJ72MweBTYvUgK+bewKDDXGHZSQFhpYbvpU08D2ZgmezNok3dPOwaaEj9dY6gd3TucVhAoEmCPiqCH0TY7z3vSU8znhk+MViTY6LurA3s/rT7ka+q45l7u3ga3egILC1w/7Sd14IAqufRjxdPYk4iETWIx7ROaTI09K1nlPny2+VWu3qVy98KV9gkyeLLh4juKnjFFZFwJgT6zwTy7UaZJ//fPHCvvGNUtcloNGL+bIYused06JDrnpO810r4REE1std0u0gC0VgoKC0QFxGslhq0skbC9vSLBxJ6ZkVKq0ID+yCC4qYg5hKBw+cyQg/ENmf/ElKe+9dunb3kJZrefaxWyCwhIBIwoMeVMKEiMp9iVN8XSzG5Lfcu70YlYdkGl2+NyRhFHtfIAsCG8HFXDgCgylXyewgcRBJYlXLet60MMRkntjZZ5cvu1DLNa5RpMZGqesxTGZfyUw/OIotPMo0PlWy5iHxO7/T4gRil0BgSgRI4j/3uZKvRU66rlWZu/tzjz1S2m23Ij7Spelv/7ZEFxTwq0ZR89XZnMQrX5nSk59cFMKYUlPeBbQgsBFc1IUksIrrWWcV9qBWVJUplKGQq6URUVEgKluh4qfK0tCUl2axqTamels8NE30ye05gwyHar+jhmzO89ctEYzdhkCAKENqibjv3HOX3oFWwlRykTzF+cpEEJyvgAoUEXckR/fUS89cQg0HdOObrUIu3wsrDoFa92MGgXXHsPMRFprAoMM90kpDgRd3SK+cDvPFKuBqaAg73vrWlE4+OSVteHS7x5c8s8nxLBoG+y4rGP3a14onpjhUZ++R9yvtfH/FAYZDwD2ItBTg61uoma5onUUVhaz8raGtRBkGG7tflYJofmFNJ0hhXdc5xC3iIcqhfYeTckImWnY+8HDY9XHkILA+UOx4jIUnsIoP10nVpk6k3KUXvrBMuOzBhBV5WshM+IYRdUiMe5CYO6bGBsl5iFgVf+YzKe2yS8k7yKmFBQLTIiCsbTEkBKiwmLPjd6FA/xYqxCNk8moa3V/quXSXUYxsf/er4uXOpgO2+kvyeG8s3m4ltw4sCGwEF3ndEFj1xnTtfd7zSnLAT0vWHrXwdTyLfJn8NfNWQjhWvzwzaTlERsas75xRFGGBwDQIiIqL0slpISxR8TrrVdcMRGWMnnvKIsokckXHFk9MdYm+hje5yTTvtpXXYEgJNKsxEyx5Xeowe/wudTzDwXcPApse4mvml9LC5cdfOj9vucFRumSV3c1DzQGClCPcKfvxW7d1RWAVCgop3tjHP16eApSK3KGezWpYwpy35cGjYeolE1dN+BCfylWEBQLbQoAeQmTumvlpoPEMVawoHd2E0keOkHtKTf+kmlAzXv8nbCg3SynbycTMDzmkdMChTkJi1752p0PO485BYNNftby8SbkKMOX1VsoJnZR1cClnUVa0fGsnd5PXB4GthrFvvcFf2AOr6GYqUdBBcj/N5ZSrQGYWqgqhLV4l0Lfffl0tXqeBKl6zGQHek2a6ShsJgYSqawcmc+2EBitpKfkYTO3KnZO8FfdWHyKfvI5nDAWBTf8VPSe/dM+8aaVJ7Loxbyu10tyQ/54zqSkHCVLuWBYEtk2IJbCOOqrIuNSp+F1mu4NacbX3tGC9053KDLLlJkcmJacQWo9TW/39RjcqeQzPjF7UYtsEJV4wFgSsrTSUNmASiYnUuVcoCnnvCpL16dSIRmHyIOpWs4ZUP5PHuwGJogg21vnNGAQ2/bckN/xLudRwk+WgwabwYf13PUpe0yfZlKxQSNKzQWDT41sy3r6YOphyjXxhtSTwtOjJ5CdEXxglmKYEiMpcMp4ZFbL8Rd38m3S/moeTfRRTW/j6qSYtbP4QEAAgede6SY2hLksK36Vkq4l0u0/kVUW5pZgIMKy1BAt0ixfBQ2SDzKhTJ6IAWa6YmvfRjy5qETdtWA7fXk6W23N29IY0hra8xkor3Rm5T3TKE6i2ICwEtvzRJVyYKweTcOOBm4FdLYT4mPz/thwP32nDBQLjYQUBeTGrS2265cV8eUkJe5AEC++oGRM+pDxmvKzb377kLGxaU9WGBR5yHmyKoj3shB4//emUFEtTlzmO1yNGq3QeWti4EdC1RR0hkU+t2RI+5lExpCQ8qF5Lw3Y5LRE7nV3UE/KytH7yb9yiM3zvJmap7qPKHBUia77ben5K72c4igMGgU1/GaYJIebIeDIUy6Mx695SDiykXKK4KWe2qq1LEce2cMccdMbCiWT3pIKayIn/9UBkCks9hGrXDj/rwwwpUSvSltiQm/K1SXEXj80+BCImsfvdKXvgqe0h2w8bDwK8a6N5DELlbXHqlSIqs5DTQlqGqKrfqmIfHrYBk7UIXqoWkclvCSNWAUevnxJxue9FHyiOFJZ5M/L4sMsgEAQ2/U2RZT4pJ2suFXFQJR6xld0PzP8XIcTp8V35lZhG7EYlqHgeRjE4icvTA5FNvilPS19FZES1qB1VXZXrU7chZzeFD3lZVGQ8NwIQK3QemtW4Vb3VuxBkj5HPriiu2/0Vrbt1ODMWHbxlUWn9COU7hQMtONxS8pwWJBYiFi3CxcLN+he+4AXlelpP6dDUe3rWyWFYmnyqEHVcTtyU5J7v80W6GYLApr+autHmWzkRwIr3kdFTGSKprAdPuafDFhYENj22236l+L+nkNWocKueUfosahY8EFMIMcqBVC/tjDOKDFrocGvmlBBZ2NohIHUk8kxd7jrKUxG51koNJIWseFU8Mp6YvBZ5vAJleTC1g1pEMd1dHI+H1qs50de8ppyoQXfikdhU4m0d1XO1xTQIrC1yPe4XIcQGYFJUSGDIB2AXsT3CD08YUrCBzYqdt2VlTxj2wx8WkQcO9fATXhJ28n/CUnjX/3Mk68/6u1MlIuPd8eZ4dYqs5WPCLosA/Iwb4RXDCF7LnRPEJM8pheoaPeQh5VapsnbYa5pLOcjb9nfelUVHPZYFig4Zn/pUOQc/RfJ6NUNgNUDktotvCo0jLm8cHtfUUAeBTQ3VcC8MAmuBLSbRCVWYRUsEEjBdeqm0Zty81EPT277tbYWwuhpVoy4NQpW6h1A6+rmeFuSIRi5KKBfREFQogardLGCs0kIxcTW3AYGFjkpCvVpvwo6dkzPYipDlwPCFkgjeF89speHhSEyHJo5+r7J4LjziUv9o9SPxJi4ZOa5WX5sgsFaw9btTEFgHPLHHqaeWJbWfnjaW0wcfXJ5eM1jN4tE6rULin4DDA/SWtyyeghwZ53Dyp9+dmgelOiMdQ9SmqVOjWfGwVlUgl8bMIhRp6qEHcgewh92VQ23CgJaZiKuGaoXtRNYIa7RhQlQa6Oo/qCUTsiNp50mpgbemEQL0d3oIuCE1t4bI3GOy9pdcfmYLAq6j8ctOmmbfzSAJp6hsgYZLDnt3rHz0ILC1QH3ZewaB9XQRPPV1JpDEEKKR8EBkGgfXoUw9vdXkYfRU9GBcyQg6OISTG2dx8t/EBMKOk1zr4YvUNCZWY2ThTi2Ho7dm+LwSolCb4/ibh7UHuGcnAYKwpfftI+oqx8SrETYlhNGiz/sJqdIiGEm1mnFCeK68o9q3krdpISBsR7NT804w0NldiJCanMDC5zN5gIfGC5anEmbUz5aT4zbgbZk6YFD4TKd1u4A+GBGSkxKv1E9KI8V12PZpgK9e1IENAWrTYwaBNUVsG6/3BJUns+K1XFfUZfiSjQxtAK/Mg9IzygOZWNKzi/fk5+Tv/jZZGF0/iRyaB71T81BeLhShgPRx1KnVPByxWt1wt995b1V4sC1Ukczv/34RdOoJuy2O99l4RlXM4r3kmXy+ydDe5PsiSjmk5c3RhQc1ldCSyflaa3iuk6ZPCiVcSqOtCCx4WzDiuIi6IS1emBDgy15WcEVc3g8x6/rO20KGA1zyleEFBBfSaBOae/92kvoWAnogwdG2rvWi/n94YCO4skFgA10ErgctvCc/WSCpMtEHj8wmLjdj463onIXsKrkRe/CWCNKY8GL1kIg6NF1QEiQXpLabp1Jf6/WEIEJrNoRkH16e8KX/8/D2vogPBPJ0vDThSqptJi3DOZg0JIqwqPVs3tsxGAGF9yI9Rzg8St6NEB4PD7lQ/TEtmNTHIWbrCk4yZSfiEUnT0xkx16a4PC2d3PGAfZ2v9+Bh4YHag5D+AZkxeFlEuLxeJ7c1MyenjmEmg/cBuaISmVw+oHZuOz/jm3SO3i4IbAQXKwhsBhcBQyCxt7xlqTJV4lxRkGW/eNcIjZBA/geZICMpEyM6iAuExpAIstpaPsfzlffEW+Kl1QJuHdLBIhyHLJAR8jBiBmHxZLwvp4HjioSI5bz/cqWk93CuuoDJOyFZNXJCfp7hwnlyU1oyGS1Cb8MhRjxyX1JDCoZtCJ0h5H32KflFXtRy58W5yzP6XLDgfc3U21LOwYVEXD4Et+9e9yr3lBNf530KZ/F1CgKbBcrbeI8gsBlfBDr4+uDh2njwUIPtv38J83iqjsQQgG5CTA6MCZXVTYTK737yjvysv/s7j4u3tjxsyVMxw0qdLAeBtNw4EG2WmJAewrJ5HTJi3kO5Eu8NGVL3IURhRXkwJtzpGY6geI0IzOuRoIa3CBNR8bJsVaii/aWGK0jIz2kcZN4Zkp1ZP0psSZAhEWcFwIiFePQWQjM7kZHcoGt8GkFga3wByhd+w6/P8AQImy0C3AbJmBr68SSldPAE9WSnzOg8uKnbR+KZVOUhcUNVMwoz2pxu/clD8W+b3/1dmE7eSGhPGA4pyEdVQpI7qqE+DqmQHtJCDHJckxsSwv2TZOg9HM+58c7sy5OrhsyEE6n+aqeL2vZTyNFnQ1Y23uTMclXTXhb3CDkoqSnXtCpN1DggLQqSaZh22veL1zVCIAisEVzDvDgIbBhcGx1VkkhixkPKJiTEPJmRmVYN9PGje8I2+pSXebGPxqFAckJ7vCq5pEmTcxLO85y2ybHVnBth3dbqpKj/CDAYxxZRIS2b9xslnFxY8s96L2Bupr8UwGwIbJQn3+1+mLe9g8BGcMWCwEZwEZafgtnwHmBW3pQMVuK8MZ0SuBmexDMumB4CpRe+cGkaNS+p5tUqQSGs6q21eX+yejkxJEfTMEoRnmtLxinxJ6bppxOXw3K9Eda++8YIkzY3wMD7BIENDPA0hw8CmwalNXwNXbxxuxQKYnrVRRE740pUdUPkP9bwIjV8a7msmoRDWP7NJOJcT4RF/r6t2oKGbxsv7xeBILB+8Wx1tCCwVrCtzU5UDPJmdaWuxUOt3N1tt+KZ1eFivXd+XZuPPPfvKjzMwxIiNszNteNhM8nBGtNEXFzQCA3OzSUPAhvBpQoCG8FFaHsKipvqYDAPRnVnVeVA316nZNKe08PXSZlt3y/22zYCdPiuSZ2N42f1mnlUZJXICnHJa86sp9S2Tz1e0QyBILBmeA3y6iCwQWBdm4PSdJvP4QFaH6JW/8yDUtgRmdGpa+6nkEmlcqz6m18vnpXCMgVoNp4xsqqiC3jDGd51IUE5MspEXPOPH3v42lwuVxxuGmk1esv9BBbTgsAW87pe+qm03vBgrR6Blha1aMqL5M6Q2eSG2LSSCGIrAhr6/UpUZO1+V8MnfFuNyKaSlZ80/JpMhi0sAkFgI7i0QWAjuAizPgXthuqDuD6Y/dTjqRr5H826rerX67/9HFHBdSf4EBQ8eFOrbZPNIYVmlxM+zzYGqXW6DPO4cxDYCK5aENgILsIYTsGDXIPESmiqiOsDXVhseZfeOtVRW3ne2vJt8u/IbpahM3lAUnT5qDrd0++Tm79TePKulg9SI66YJGvtQipphdpzDHfrKM4hCGwElyEIbAQXYeyngNwQwnIPxcN/khQ0CFzNtPEQUrOpXJ786XddeKchOYW+Qnd6VNlW+n219vRCovpOVrJFspNE5XfV0SF2GfsdOYrzCwIbwWUIAhvBRViUU9D8UH5tuafzv/+7JdmsRDr+hii3ZXX2y2pkiBxtk0RVCYtn1euI422dbPz/IiMQBDaCqxsENoKLEKcQCAQCc4dAENgILlkQ2AguQpxCIBAIzB0CQWAjuGRBYCO4CHEKgUAgMHcIBIGN4JIFgY3gIsQpBAKBwNwhEAQ2gksWBDaCixCnEAgEAnOHQBDYCC5ZENgILkKcQiAQCMwdAkFgI7hkQWAjuAhxCoFAIDB3CASBjeCSBYGN4CLEKQQCgcDcIRAENoJLFgQ2gosQpxAIBAJzh0AQ2DguWW4Sly4Yx6l0Potr5SPkVhALb/E5F+sSx/Wcz+uZ+46l3Ah0/Law41TGD32jMzwjv3ou5vM0+lSXfXF8zo4Ajmz3uJ4juyCLdjpBYPNxReNBMB/XadqzjOs5LVLz8br1cj1HdzWCwEZ3SVY8ofXyBYnPOR/347RnGddzWqTida0QCAJrBdvMd3pMfscTZv6us3/D+Jyzx3zId4zrOSS6cewUBBY3QSAQCAQCgcBcIhAENpeXLU46EAgEAoFAIAhsnPdAHq+bTszbjfN2ft4emLdLVjnV385//2Le3pO3vxrnx1n1rKb5nLvmvV+RN5/zl3l79mZs5uGj3j2f5HF5+828vSZvxyw76Svmf78pbxvy9t28PWjz9Z6HzzZ5jtv6nE/KL/7LvOWx00l5y6PyNo8lLtv6nBWT++dfTsrbbfImDxg2EAJBYAMB2/Gwz8/751n3mx54R+btGnl7yirH9IBUs+H180Zg03zOm+bPZaTxuXm7Qd7OzNvOeft+R4yH3h1p/Xfe9s7b1/L2b3l7SN4sNqodnH+5Vd4el7cH5+2+eUNi82TTfM475w/0L3nL46nTQXnbc0E/p+u2Xd4+mLcr5M33MQhswLs5CGxAcDsc+pzNX/Jv5p/Xz9vGvN1sheNZuR+et1Pypk5s3ghs2s85+dHPzv/YP28Ibcy2ez65Z+Ttzzaf5FGbfz534qRP3fyaz+Sfl8/bRXmzGEHY82LTfM7Jz3Lr/I+X5W2PefmAm89z2s/5D/n1H9n8vTws/wwCG/BCB4ENCG6HQ/Murr55f9dI+LD+ux72N/IvH83bw/K2V97mkcCm+ZyTMN42/+ONebtF3n7VAd9Z7IpkhZyEztjD83a7vE0uMv5j82t4aOy8za+Zp64r03zOSbyRF6J+1iwuQo/vMc3n3C2/31PzJoS4MW9BYD1egJUOFQQ2MMBbOfxp+f+ut8L/+wJ4SE8SFgITRpw0D8Kr5E0Y7sC8jZXAun7O+pmrJ/qI/IfPrt1lm/qdp3ngrTcCs9hy394pbz+fGslxvHBb17MuKH0Xz8/bxrwFgQ187YLABga45eGnCa29NR/7jnnjiVwtb2Lux+dNzmxebJrP6bMQcHggPCdvkuPzYNOEnNZTCFGU4KV5Q14Xz8MFXHaO27qe2+fX86B/tHk/i1N56f3yFmHEgS54ENhAwHY87LF5f6q0KuKg1jtiK8c8MP/fWD2wrUExzedEzCfn7f15k1+YF5PTIuK4a96+njcijgPy9p8TH+CQ/Psueasijvvl3ylO58mm+ZzyXhYeQqpjz12uhv00n3Ny3435H+GBDXwnB4ENDHDLw++Q93tH3nbKG7mxh5rVHJLysKt5lXr4Azf/37yJOKb5nMJOr1/24Pd5z2qJ7Sx3u0d+M6RLqfe6vCkBeGberMjfl7cr5e3NefOAd30pEb88yxPs6b229TmFkRE1URK7MG88k3mzbX3Oyc+zMf8jCGzgKxwENjDAcfhAIBAIBAKBYRAIAhsG1zhqIBAIBAKBwMAIBIENDHAcPhAIBAKBQGAYBILAhsE1jhoIBAKBQCAwMAJBYAMDHIcPBAKBQCAQGAaBILBhcI2jBgKBQCAQCAyMQBDYwADH4QOBQCAQCASGQSAIbBhc46iBQCAQCAQCAyMQBDYwwHH4QCAQCAQCgWEQCAIbBtc4aiAQCAQCgcDACASBDQxwHD4QCAQCgUBgGASCwIbBNY4aCAQCgUAgMDACQWADAxyHDwQCgUAgEBgGgSCwYXCNowYCgUAgEAgMjEAQ2MAAx+EDgUAgEAgEhkEgCGwYXOOogUAgEAgEAgMjEAQ2MMBx+EAgEAgEAoFhEAgCGwbXOGogEAgEAoHAwAgEgQ0McBw+EAgEAoFAYBgEgsCGwTWOGggEAoFAIDAwAkFgAwMchw8EAoFAIBAYBoH/D4pJPR/gKqlqAAAAAElFTkSuQmCC\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 25.93 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Minimum Arm Width: 51.71 um\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "(<Figure size 432x288 with 1 Axes>, <AxesSubplot:>)"
+      ]
+     },
+     "execution_count": 147,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "filename = \"design_v4rdso2_inner.txt\"\n",
+    "hole_to_SC_curves(inner_x_smooth, inner_y_smooth, filename, num_holes=36)\n",
+    "filename = \"design_v4rdso2_outer_1.txt\"\n",
+    "hole_to_SC_curves(outer_1_x_smooth, outer_1_y_smooth, filename, num_holes=36)\n",
+    "filename = \"design_v4rdso2_outer_2.txt\"\n",
+    "hole_to_SC_curves(outer_2_x_smooth, outer_2_y_smooth, filename, num_holes=36)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Segment outputting"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 148,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "plt.close('all')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 150,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def hole_to_segment(finalHoleX, finalHoleY, filename):\n",
+    "    printstring = \"\"\n",
+    "    for i in range(len(finalHoleX)):\n",
+    "        printstring += f'{finalHoleX[i]} {finalHoleY[i]}\\n'\n",
+    "    with open(filename, 'w') as file:\n",
+    "        file.write(printstring)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 155,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#original hole\n",
+    "filename = \"original_segment.txt\"\n",
+    "hole_to_segment(filterX, filterY, filename)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 156,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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\" width=\"432\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fig,ax = plt.subplots(1,1)\n",
+    "ax.plot(filterX,filterY)\n",
+    "ax.set_aspect('equal')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3 (ipykernel)",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.9.10"
+  },
+  "toc": {
+   "nav_menu": {},
+   "number_sections": true,
+   "sideBar": true,
+   "skip_h1_title": false,
+   "title_cell": "Table of Contents",
+   "title_sidebar": "Contents",
+   "toc_cell": false,
+   "toc_position": {},
+   "toc_section_display": true,
+   "toc_window_display": false
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/notebooks/singlehole.stl b/notebooks/singlehole.stl
new file mode 100644
index 0000000000000000000000000000000000000000..01ab4d663e2e961d4007d4cbd31c51b68d514fae
Binary files /dev/null and b/notebooks/singlehole.stl differ
diff --git a/resources/designs/original_segment.txt b/resources/designs/original_segment.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1a50513d42f768c253c446c54f0b868597aeff8e
--- /dev/null
+++ b/resources/designs/original_segment.txt
@@ -0,0 +1,81 @@
+0.08342350190651371 0.46549519868335076
+0.07841772580206026 0.4653553216332829
+0.07347544397114672 0.46523927433984263
+0.06841087147880782 0.4651285361959176
+0.06324306221857788 0.4650236355132837
+0.05794831601146835 0.46489821751468646
+0.05256536505405335 0.4646312038485568
+0.0467241973288577 0.4639873975114924
+0.04096758653167344 0.46285166867679645
+0.035524711878633194 0.46132665785379745
+0.030713126740890065 0.45953426090020066
+0.02683166748622548 0.4575609731692809
+0.0242140491431741 0.45553148742171956
+0.022997204287084974 0.45356369579002237
+0.023137802429556417 0.4517854335713703
+0.024798900737669882 0.45028580472192564
+0.02785056543165819 0.44908023559664284
+0.03196750213819188 0.4481600300678896
+0.036978412466203786 0.44756655729109146
+0.04247022518459276 0.4472806736515615
+0.04792128223920712 0.44715684084545254
+0.05285404140853385 0.4470956879352213
+0.05760231125444312 0.44719555236819464
+0.062192278914288794 0.4476095981386217
+0.06671618467673737 0.4483434972759393
+0.07138550690536788 0.44935714664624216
+0.07609549932841755 0.4506094917808526
+0.08083318175161396 0.45202964006229546
+0.0854707278907869 0.45352517439906564
+0.09043423284978158 0.4549675138324807
+0.09559422299143723 0.45622657845777453
+0.10099755382749764 0.4572556238895831
+0.10645158115860563 0.4580700275924763
+0.11203181654210213 0.45863071546455053
+0.11759426340922347 0.45891182560775395
+0.12313754195083652 0.4589293409002886
+0.12863880976270664 0.4586853532565169
+0.13394213303045188 0.4582048043621995
+0.1391883628498748 0.4574351510546052
+0.14433265056760644 0.45640399636461737
+0.1493421784475492 0.45515566034553345
+0.15419564663068563 0.4537498451804335
+0.1587903703688843 0.45226280795579843
+0.1635973224795519 0.45074563559663205
+0.16848621024808919 0.4492631111174751
+0.1734823080549761 0.44788120272301896
+0.17862841362191353 0.4466147410052318
+0.18433949150513332 0.4454691615798391
+0.19048444371526638 0.44462584722012366
+0.19643992016352538 0.44429312197716647
+0.2017209578492061 0.444491688317236
+0.20594718477767693 0.44520637152729425
+0.2090460485799926 0.44633687969047203
+0.2107385832438895 0.4478708467433733
+0.21096808365683925 0.44975275029332273
+0.20985601165966195 0.4518598699326194
+0.2073114080618421 0.45415911879898346
+0.20375484593148496 0.4565096064138949
+0.1993583589420156 0.4588082375031357
+0.19450707937761202 0.46095281880941374
+0.18965720604039044 0.46291876033358514
+0.1851842557204474 0.4647881206648992
+0.18111159225194168 0.4666753344760386
+0.17676177423050082 0.4684915868766098
+0.17215580592463958 0.4700392952441131
+0.16731269534056573 0.4712221319681888
+0.16226452237289327 0.471985694125172
+0.15705086472735147 0.47231123826247445
+0.15172356604424542 0.4722183034773801
+0.14631916726713506 0.47174039717221306
+0.1406977261600108 0.4710095820727771
+0.1350132029346256 0.47007927336447486
+0.12932059457620468 0.46906174086219776
+0.12371407043707341 0.46808700610678156
+0.11818231749165288 0.46729765171367377
+0.11295161095285076 0.4667436418556796
+0.1079742919840697 0.4663901598312506
+0.10308785065022087 0.4661179057190045
+0.09819581976071053 0.4659214724413688
+0.09329267907051014 0.4657693551945077
+0.08837329881141934 0.46563391136495635
diff --git a/resources/shaders/segment_line.vert b/resources/shaders/segment_line.vert
index 57bf7663a104912359a0888d2280bee79b211ea7..d011e9d710d8bc421fc912baf2c195c5ffb99834 100644
--- a/resources/shaders/segment_line.vert
+++ b/resources/shaders/segment_line.vert
@@ -1,7 +1,20 @@
 #version 330 core
 layout (location = 0) in vec2 vpos;
 
+uniform mat4 model;
+uniform mat4 view;
+uniform mat4 projection;
+
+uniform float rot_angle;
+
+uniform vec2 offset;
+uniform float zoffset;
+
 void main()
 {
-    gl_Position = vec4(vpos.x, vpos.y, 0.0, 1.0);
+    float x0 = cos(rot_angle) * vpos.x - sin(rot_angle) * vpos.y;
+    float y0 = sin(rot_angle) * vpos.x + cos(rot_angle) * vpos.y;
+    float x1 = x0 + offset.x;
+    float y1 = y0 + offset.y;
+    gl_Position = projection * view * model * vec4(x1, y1, zoffset, 1.0);
 }
\ No newline at end of file
diff --git a/src/arm_designer.cpp b/src/arm_designer.cpp
index 4e787ef77d4264711b6dae97549c3743adcae9b6..b42fca682c4fdbc6e1c85ed3b360d5461ff0e744 100644
--- a/src/arm_designer.cpp
+++ b/src/arm_designer.cpp
@@ -1,5 +1,7 @@
 #include <arm_designer.hpp>
 #include <iostream>
+#include <cmath>
+#include <utility.hpp>
 
 ArmDesigner::ArmDesigner() {
 		infra_.init("Arm Designer", WIDTH, HEIGHT);
@@ -14,13 +16,17 @@ bool ArmDesigner::run(){
 			break;
 		}
 
+
+
+		renderer_render_();
+
+
+
 		gui_new_frame_();
 		gui_draw_debug_window_();
 		gui_draw_controller_window_();
 		gui_finish_drawing_();
 
-
-
 		SDL_GL_SwapWindow(infra_.window());
 
 #ifndef NDEBUG
@@ -52,6 +58,8 @@ void ArmDesigner::gui_init_() {
 	ImGui_ImplSDL2_InitForOpenGL(infra_.window(), infra_.context());
 	const char* glsl_version = "#version 330";
 	ImGui_ImplOpenGL3_Init(glsl_version);
+
+	gui_params_.enable_drum_contour = true;
 }
 /*GUI Start Drawing*/
 void ArmDesigner::gui_new_frame_() {
@@ -75,22 +83,52 @@ void ArmDesigner::gui_draw_debug_window_() {
 	}
 	else {
 		ImGui::Text("Mouse Coordinates: (%5.f, %5.f)", ImGui::GetIO().MousePos[0], ImGui::GetIO().MousePos[1]);
+
+		float mouse_x = ImGui::GetIO().MousePos[0] / static_cast<float>(WIDTH);
+		float mouse_y = (HEIGHT - ImGui::GetIO().MousePos[1]) / static_cast<float>(HEIGHT);
+		float scale = std::abs(render_params_.zoffset) * 2.f * std::tan(glm::radians(render_params_.fov / 2.f));
+		ImGui::Text("Real Mouse Coordinates: (%.6f, %.6f", -(render_params_.offset.x - (mouse_x - 0.5) * scale), -(render_params_.offset.y - (mouse_y - 0.5) * scale));
 	}
+	ImGui::Text("FOV: %1.f", render_params_.fov);
+	ImGui::Text("Horizontal Distance: %.1f um", std::abs(render_params_.zoffset) * 2.f * 1000.f * std::tan(glm::radians(render_params_.fov/2.f)));
+	ImGui::Text("Center Coordinates: (%.3f, %.3f)", render_params_.offset.x, render_params_.offset.y);
 	ImGui::End();
 }
 /*GUI Draw Controller Window*/
 void ArmDesigner::gui_draw_controller_window_() {
 	ImGui::Begin("Controller", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
 	if (ImGui::Button("Load")) {
-		segments_.load(gui_params_.segment_load_path);
+		segments_.load(RESOURCEPATH + std::string("designs\\") + gui_params_.segment_load_path);
+		segments_shown_.push_back(true);
+		segments_repetitions_.push_back(1);
 	}
 	ImGui::SameLine();
 	ImGui::InputText("Filename to Load", gui_params_.segment_load_path, IM_ARRAYSIZE(gui_params_.segment_load_path));
 	if (ImGui::Button("Save")) {
-		segments_.save(gui_params_.segment_save_path);
+		segments_.save(RESOURCEPATH + std::string("designs\\saved\\") + gui_params_.segment_save_path);
 	}
 	ImGui::SameLine();
 	ImGui::InputText("Filename to Save", gui_params_.segment_save_path, IM_ARRAYSIZE(gui_params_.segment_save_path));
+	if (ImGui::Button("Clear Segments")) {
+		segments_.clear();
+	}
+	if (ImGui::Button("Reset View")) {
+		reset_view_();
+	}
+	ImGui::Checkbox("Draw Drum Contour", &gui_params_.enable_drum_contour);
+	ImGui::Text("Segment Info");
+	for (size_t i = 0; i < segments_.size(); ++i) {
+		int reps = segments_repetitions_[i];
+		ImGui::Text("Segment %i", i);
+		std::string name = std::string("Segment " + std::to_string(i) + " reps");
+		ImGui::InputInt(name.c_str(), &reps);
+		segments_repetitions_[i] = reps;
+		/*Bug: Cannot directly address entry in a vector of booleans*/
+		bool shown = segments_shown_[i];
+		name = std::string("Segment " + std::to_string(i) + " shown");
+		ImGui::Checkbox(name.c_str(), &shown);
+		segments_shown_[i] = shown;
+	}
 	ImGui::End();
 }
 /*GUI Finish Drawing*/
@@ -104,6 +142,7 @@ void ArmDesigner::gui_finish_drawing_() {
 void ArmDesigner::renderer_init_() {
 	render_params_.resource_path = RESOURCEPATH;
 
+	/*Segment objects*/
 	glGenBuffers(1, &render_params_.vbo_segment_nodes);
 	glGenVertexArrays(1, &render_params_.vao_segment_nodes);
 	glBindVertexArray(render_params_.vao_segment_nodes);
@@ -113,9 +152,145 @@ void ArmDesigner::renderer_init_() {
 	glBindVertexArray(0);
 	glBindBuffer(GL_ARRAY_BUFFER, 0);
 
+	/*Grid objects*/
+	for (size_t i = 0; i < 201; ++i) {
+		render_params_.grid_coords.push_back(-1.f + i * 0.01);
+		render_params_.grid_coords.push_back(-1.f);
+		render_params_.grid_coords.push_back(-1.f + i * 0.01);
+		render_params_.grid_coords.push_back(1.f);
+		render_params_.grid_coords.push_back(-1.f);
+		render_params_.grid_coords.push_back(-1.f + i * 0.01);
+		render_params_.grid_coords.push_back(1.f);
+		render_params_.grid_coords.push_back(-1.f + i * 0.01);
+	}
+	glGenBuffers(1, &render_params_.vbo_grid_nodes);
+	glGenVertexArrays(1, &render_params_.vao_grid_nodes);
+	glBindVertexArray(render_params_.vao_grid_nodes);
+	glBindBuffer(GL_ARRAY_BUFFER, render_params_.vbo_grid_nodes);
+	glBufferData(GL_ARRAY_BUFFER, render_params_.grid_coords.size() * sizeof(float), render_params_.grid_coords.data(), GL_STATIC_DRAW);
+	glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), static_cast<void*>(0));
+	glEnableVertexAttribArray(0);
+	glBindVertexArray(0);
+	glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+	/*Drum contour objects*/
+	for (size_t i = 0; i < 365; ++i) {
+		render_params_.drum_coords.push_back(1.05 * 0.5 * std::cos(2.f * M_PI * static_cast<float>(i) / 365.f));
+		render_params_.drum_coords.push_back(1.05 * 0.5 * std::sin(2.f * M_PI * static_cast<float>(i) / 365.f));
+	}
+	glGenBuffers(1, &render_params_.vbo_drum_nodes);
+	glGenVertexArrays(1, &render_params_.vao_drum_nodes);
+	glBindVertexArray(render_params_.vao_drum_nodes);
+	glBindBuffer(GL_ARRAY_BUFFER, render_params_.vbo_drum_nodes);
+	glBufferData(GL_ARRAY_BUFFER, render_params_.drum_coords.size() * sizeof(float), render_params_.drum_coords.data(), GL_STATIC_DRAW);
+	glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), static_cast<void*>(0));
+	glEnableVertexAttribArray(0);
+	glBindVertexArray(0);
+	glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+
+
+	/*Line shader*/
 	std::string vertpath = render_params_.resource_path + "shaders\\segment_line.vert";
 	std::string fragpath = render_params_.resource_path + "shaders\\segment_line.frag";
 	render_params_.shader_segment_lines = Shader(vertpath.c_str(), fragpath.c_str());
+	render_params_.shader_segment_lines.use();
+	glm::mat4 unity(1.f);
+	render_params_.shader_segment_lines.setMat4("view", unity);
+	render_params_.shader_segment_lines.setMat4("model", unity);
+	render_params_.fov = 60.f;
+	glm::mat4 projection = glm::perspective(glm::radians(render_params_.fov), 1.f, 0.f, 100.f);
+	render_params_.shader_segment_lines.setMat4("projection", projection);
+	render_params_.offset = glm::vec2(0.f, 0.f);
+	render_params_.zoffset = -1.f;
+	render_params_.shader_segment_lines.setFloat("zoffset", render_params_.zoffset);
+	render_params_.shader_segment_lines.setVec2("offset", render_params_.offset);
+	float rot_angle = 0.f;
+	render_params_.shader_segment_lines.setFloat("rot_angle", rot_angle);
+
+
+	render_params_.color_segment_lines = glm::vec3(0.f, 1.f, 0.f);
+	render_params_.color_segment_points = glm::vec3(1.f, 1.f, 1.f);
+	render_params_.color_segment_rep_lines = glm::vec3(0.f, 0.3f, 0.f);
+	render_params_.color_segment_rep_points = glm::vec3(0.3f, 0.3f, 0.3f);
+	render_params_.color_segment_sel_lines = glm::vec3(1.f, 1.f, 0.f);
+	render_params_.color_segment_sel_points = glm::vec3(1.f, 1.f, 0.f);
+	render_params_.color_grid_lines = glm::vec3(0.25f, 0.25f, 0.25f);
+	render_params_.color_drum_lines = glm::vec3(0.7f, 0.0f, 0.0f);
+
+
+
+
+}
+/*RENDERER Render*/
+void ArmDesigner::renderer_render_() {
+	glClearColor(0.f, 0.f, 0.f, 1.0f);
+	glClear(GL_COLOR_BUFFER_BIT);
+
+	/*Update zoom*/
+	glm::mat4 projection = glm::perspective(glm::radians(render_params_.fov), 1.f, 0.f, 100.f);
+
+	//first we render the grid, it's in the background
+	glLineWidth(0.3f);
+	render_params_.shader_segment_lines.use();
+	render_params_.shader_segment_lines.setVec3("color", render_params_.color_grid_lines);
+	render_params_.shader_segment_lines.setMat4("projection", projection);
+	render_params_.shader_segment_lines.setVec2("offset", render_params_.offset);
+	glBindVertexArray(render_params_.vao_grid_nodes);
+	glBindBuffer(GL_ARRAY_BUFFER, render_params_.vbo_grid_nodes);
+	glDrawArrays(GL_LINES, 0, render_params_.grid_coords.size() / 2);
+	glBindVertexArray(0);
+	glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+	//next draw drum contour if enabled
+	if (gui_params_.enable_drum_contour) {
+		glLineWidth(2.f);
+		render_params_.shader_segment_lines.use();
+		render_params_.shader_segment_lines.setVec3("color", render_params_.color_drum_lines);
+		glBindVertexArray(render_params_.vao_drum_nodes);
+		glBindBuffer(GL_ARRAY_BUFFER, render_params_.vbo_drum_nodes);
+		glDrawArrays(GL_LINE_LOOP, 0, render_params_.drum_coords.size() / 2);
+		glBindVertexArray(0);
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+	}
+
+	//now draw all segments
+	auto segs = segments_.get_segments();
+	for (size_t i = 0; i < segs.size(); ++i) {
+		if (!segments_shown_[i]) {
+			continue;
+		}
+		auto seg = segs[i];
+		auto nodes = seg.nodes();
+		render_params_.shader_segment_lines.use();
+		glBindVertexArray(render_params_.vao_segment_nodes);
+		glBindBuffer(GL_ARRAY_BUFFER, render_params_.vbo_segment_nodes);
+		glBufferData(GL_ARRAY_BUFFER, nodes.size() * 2 * sizeof(float), nodes.data(), GL_STATIC_DRAW);
+		for (size_t k = 0; k < segments_repetitions_[i]; ++k) {
+			float rot_angle = k * 2. * M_PI / segments_repetitions_[i];
+			render_params_.shader_segment_lines.setFloat("rot_angle", rot_angle);
+			if (k == 0) {
+				render_params_.shader_segment_lines.setVec3("color", render_params_.color_segment_lines);
+			}
+			else {
+				render_params_.shader_segment_lines.setVec3("color", render_params_.color_segment_rep_lines);
+			}
+			glDrawArrays(GL_LINE_LOOP, 0, nodes.size());
+			glPointSize(4.f);
+			if (k == 0) {
+				render_params_.shader_segment_lines.setVec3("color", render_params_.color_segment_points);
+			}
+			else {
+				render_params_.shader_segment_lines.setVec3("color", render_params_.color_segment_rep_points);
+			}
+			glDrawArrays(GL_POINTS, 0, nodes.size());
+		}
+		glBindVertexArray(0);
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+		float rot_angle = 0;
+		render_params_.shader_segment_lines.setFloat("rot_angle", rot_angle);
+	}
 }
 
 /*INPUT handle*/
@@ -126,7 +301,74 @@ bool ArmDesigner::input_handle_() {
 		switch (event.type) {
 		case SDL_QUIT:
 			return false;
+		case SDL_MOUSEWHEEL:
+		{
+			float mouse_x = ImGui::GetIO().MousePos[0] / static_cast<float>(WIDTH);
+			float mouse_y = (HEIGHT - ImGui::GetIO().MousePos[1]) / static_cast<float>(HEIGHT);
+			float scale = std::abs(render_params_.zoffset) * 2.f * std::tan(glm::radians(render_params_.fov / 2.f));
+			if (mouse_x < 0.f || mouse_x > 1.f || mouse_y < 0.f || mouse_y > 1.f) {
+				break;
+			}
+			render_params_.offset.x -= (mouse_x - 0.5) * scale;
+			render_params_.offset.y -= (mouse_y - 0.5) * scale;
+			SDL_WarpMouseInWindow(infra_.window(), WIDTH / 2, HEIGHT / 2);
+			render_params_.fov -= event.wheel.y;
+			if (render_params_.fov > 90.f) {
+				render_params_.fov = 90.f;
+			}
+			if (render_params_.fov < 1.f) {
+				render_params_.fov = 1.f;
+			}
+		}
+			break;
+		case SDL_MOUSEMOTION:
+			if (gui_params_.selection_mode == SEL_MODE::NONE) {
+				break;
+			}
+			/*Find node with minimal distance (or the one that appears first for equal distances)*/
+			
+
+			float mouse_x = ImGui::GetIO().MousePos[0] / static_cast<float>(WIDTH);
+			float mouse_y = (HEIGHT - ImGui::GetIO().MousePos[1]) / static_cast<float>(HEIGHT);
+			float scale = std::abs(render_params_.zoffset) * 2.f * std::tan(glm::radians(render_params_.fov / 2.f));
+			float mx = -(render_params_.offset.x - (mouse_x - 0.5) * scale);
+			float my = -(render_params_.offset.y - (mouse_y - 0.5) * scale);
+
+			auto segs = segments_.get_segments();
+
+			float min_dist = 999999.;
+			size_t min_seg_i = 9999;
+			size_t min_node_i = 9999;
+			if (gui_params_.selection_mode == SEL_MODE::NODE) {
+				for (size_t i = 0; i < segs.size(); ++i) {
+					auto nodes = segs[i].nodes();
+					for (size_t k = 0; k < nodes.size(); ++k) {
+						float dist = distance(mx, my, nodes[k][0], nodes[k][1]);
+						if (dist < min_dist) {
+							min_dist = dist;
+							min_seg_i = i;
+							min_node_i = k;
+						}
+					}
+				}
+				float tol = 0.01 * std::abs(render_params_.zoffset) * 2.f * 1000.f * std::tan(glm::radians(render_params_.fov / 2.f)); //1 percent of the horizontal view
+				if (min_dist <= tol) { //found point within tolerance
+					gui_params_.mindist_en = true;
+					gui_params_.mindist_dist = min_dist;
+					gui_params_.mindist_seg_i = min_seg_i;
+					gui_params_.mindist_node_i = min_node_i;
+				}
+				else { //no point within tolerance
+					gui_params_.mindist_en = false;
+				}
+			}
 		}
 	}
 	return true;
+}
+
+void ArmDesigner::reset_view_() {
+	render_params_.fov = 60;
+	render_params_.offset.x = 0.f;
+	render_params_.offset.y = 0.f;
 }
\ No newline at end of file
diff --git a/src/segments.cpp b/src/segments.cpp
index 9a0440a1a63c0cf68ecabc81004904ac8f14cadf..e0eb6b20ff1adde6574199453c4a7549a9eccacf 100644
--- a/src/segments.cpp
+++ b/src/segments.cpp
@@ -25,4 +25,8 @@ void Segments::clear() {
 
 const std::vector<Segment>& Segments::get_segments() {
 	return segms_;
+}
+
+size_t Segments::size() const {
+	return segms_.size();
 }
\ No newline at end of file