You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

1-Least_squares.ipynb 226 kB

5 years ago
3 years ago
3 years ago
3 years ago
3 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
3 years ago
5 years ago
3 years ago
5 years ago
3 years ago
5 years ago
3 years ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303
  1. {
  2. "cells": [
  3. {
  4. "cell_type": "markdown",
  5. "metadata": {},
  6. "source": [
  7. "# 最小二乘\n",
  8. "\n",
  9. "## 1. 最小二乘的基本原理\n",
  10. "\n",
  11. "最小二乘法(Least Squares)是一种数学优化技术,它通过最小化误差的平方和找到一组数据的最佳函数匹配, 最小二乘法通常用于曲线拟合、求解模型。很多其他的优化问题也可通过最小化能量或最大化熵用最小二乘形式表达。\n",
  12. "\n",
  13. "![ls_theory](images/least_squares.png)\n",
  14. "\n",
  15. "最小二乘原理的一般形式为:\n",
  16. "$$\n",
  17. "L = \\sum (V_{obv} - V_{target}(\\theta))^2\n",
  18. "$$\n",
  19. "其中\n",
  20. "* $V_{obv}$是观测的多组样本值\n",
  21. "* $V_{target}$是假设拟合函数的输出值\n",
  22. "* $\\theta$为构造模型的参数\n",
  23. "* $L$是目标函数\n",
  24. "\n",
  25. "如果通过调整模型参数$\\theta$,使得$L$下降到最小则表明,拟合函数与观测最为接近,也就是找到了最优的模型。\n"
  26. ]
  27. },
  28. {
  29. "cell_type": "markdown",
  30. "metadata": {},
  31. "source": [
  32. "### 1.1 示例\n",
  33. "\n",
  34. "假设我们有下面的一些观测数据,希望找到它们内在的规律。"
  35. ]
  36. },
  37. {
  38. "cell_type": "code",
  39. "execution_count": 1,
  40. "metadata": {},
  41. "outputs": [
  42. {
  43. "data": {
  44. "image/png": "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\n",
  45. "text/plain": [
  46. "<Figure size 432x288 with 1 Axes>"
  47. ]
  48. },
  49. "metadata": {
  50. "needs_background": "light"
  51. },
  52. "output_type": "display_data"
  53. }
  54. ],
  55. "source": [
  56. "%matplotlib inline\n",
  57. "\n",
  58. "import matplotlib.pyplot as plt\n",
  59. "import numpy as np\n",
  60. "\n",
  61. "# 生成数据\n",
  62. "data_num = 50\n",
  63. "X = np.random.rand(data_num, 1)*10\n",
  64. "Y = X * 3 + 4 + 4*np.random.randn(data_num,1)\n",
  65. "\n",
  66. "# 画出数据的分布\n",
  67. "plt.scatter(X, Y)\n",
  68. "plt.xlabel(\"X\")\n",
  69. "plt.ylabel(\"Y\")\n",
  70. "plt.show()"
  71. ]
  72. },
  73. {
  74. "cell_type": "markdown",
  75. "metadata": {},
  76. "source": [
  77. "### 1.2 数学原理\n",
  78. "有$N$个观测数据为:\n",
  79. "$$\n",
  80. "\\mathbf{X} = \\{x_1, x_2, ..., x_N \\} \\\\\n",
  81. "\\mathbf{Y} = \\{y_1, y_2, ..., y_N \\}\n",
  82. "$$\n",
  83. "其中$\\mathbf{X}$为自变量,$\\mathbf{Y}$为因变量。\n",
  84. "\n",
  85. "希望找到一个模型能够解释这些数据,假设使用最简单的线性模型来拟合数据:\n",
  86. "$$\n",
  87. "y = ax + b\n",
  88. "$$\n",
  89. "那么问题就变成求解参数$a$, $b$能够使得模型输出尽可能和观测数据有比较小的误差。\n",
  90. "\n",
  91. "如何构建函数来评估模型输出与观测数据之间的误差是一个关键问题,这里我们使用观测数据与模型输出的平方和来作为评估函数(也被称为损失函数Loss function):\n",
  92. "$$\n",
  93. "L = \\sum_{i=1}^{N} \\{y_i - (a x_i + b)\\}^2 \\\\\n",
  94. "L = \\sum_{i=1}^{N} (y_i - a x_i - b)^2 \n",
  95. "$$\n",
  96. "\n",
  97. "使误差函数最小,那么我们就可以求出模型的参数:\n",
  98. "$$\n",
  99. "\\frac{\\partial L}{\\partial a} = -2 \\sum_{i=1}^{N} (y_i - a x_i - b) x_i \\\\\n",
  100. "\\frac{\\partial L}{\\partial b} = -2 \\sum_{i=1}^{N} (y_i - a x_i - b)\n",
  101. "$$\n",
  102. "\n",
  103. "即当偏微分为0时,误差函数为最小,因此我们可以得到:\n",
  104. "$$\n",
  105. "-2 \\sum_{i=1}^{N} (y_i - a x_i - b) x_i = 0 \\\\\n",
  106. "-2 \\sum_{i=1}^{N} (y_i - a x_i - b) = 0 \\\\\n",
  107. "$$\n",
  108. "\n",
  109. "将上式调整一下顺序可以得到:\n",
  110. "$$\n",
  111. "a \\sum x_i^2 + b \\sum x_i = \\sum y_i x_i \\\\\n",
  112. "a \\sum x_i + b N = \\sum y_i\n",
  113. "$$\n",
  114. "\n",
  115. "上式中$\\sum x_i^2$, $\\sum x_i$, $\\sum y_i$, $\\sum y_i x_i$都是已知的数据,而参数$a$, $b$是我们想要求得未知参数。通过求解二元一次方程组,我们即可求出模型的最优参数。"
  116. ]
  117. },
  118. {
  119. "cell_type": "markdown",
  120. "metadata": {},
  121. "source": [
  122. "### 1.3 求解程序"
  123. ]
  124. },
  125. {
  126. "cell_type": "code",
  127. "execution_count": 4,
  128. "metadata": {},
  129. "outputs": [
  130. {
  131. "name": "stdout",
  132. "output_type": "stream",
  133. "text": [
  134. "a = 3.074602, b = 3.761519\n"
  135. ]
  136. },
  137. {
  138. "data": {
  139. "image/png": "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YOLEibRs2fKYr/n000+ZNm0an3/+OTk5OTRr1ozmzZsX+vpVq1bls88+49lnn2XEiBG88MILNGjQgAULFlCmTBnee+89HnzwwcOdDgszduxYypcvz9q1a1mxYgXNmjU7/HePPfYYlStXJjc3l44dO7JixQruuusuRo0axbx586hatWqRz2vatGlE75mIX7VvUI1JH2/m6P3lfstbx1KgZuDxqMtcuHAhPXr0oEKFCpx88sn07NmTBQsWAFC3bt3jgjfAokWL6NatG2XLluWUU07h6quvLvL1e/bsCUDz5s3JyMgAYNeuXVx33XU0btyYe+65h9WrVxc7xvnz53PTTTcB0LRp02MC75QpU2jWrBnp6emsXr2aNWvWFPoaoT5PJKhmLMti2tKsY4K3AX7V3N9pkGgEKoAnui6zQoUKUb9GflvalJQUDh48CMBDDz1E+/btWbVqFf/973/Zv39/RK/99ddfM2LECObOncuKFSvo0qVLoa8V6vNEgqywCZ4F5q3b5s2A8h06BAsXxuWlAxXA45Hfatu2LTNmzGDfvn3s3buX119/nbZt2xb7Na1btz4cePfs2cMbb7wR1jV37dpFzZpuRjBhwoQSn390y9pVq1YdPs7tp59+okKFCpx22ml8//33vPXWW4e/5pRTTmH37t0lPk8kWfhu483+/fDPf8K550LbtvDZZzG/RKBy4IM61T8mBw7R57eaNWtG3759ufDCCwG49dZbSU9PP5zuKMwFF1zANddcQ9OmTTnjjDNo0qQJp512WsjXfOCBB+jTpw+PPvooXbp0KfH5AwcOpF+/fjRs2JCGDRsezrefd955pKen06BBA2rXrk3r1q0Pf82AAQPo3LkzNWrUYN68eUU+TyRZFLfxJqFNqX74AZ59FsaMga1boVkzmDQJ8k78iqXAtZP1S3ewPXv2cPLJJ7Nv3z4uueQSxo0bd8ziYhCpnawEWcEiB3ATvF81r8m0pVnHPR7zmu4NG+DJJ2HiRMjOhi5d4L77oF07MCaql06adrJ+qcscMGAAa9asYf/+/fTp0yfwwVsk6Io6RLi44oeoY4m1sGgRjBwJM2dCair07g333ONSJ3EWuADuF/k5aRHxj8ImePdMXl7oc6PKjefmwuuvw4gR8MknULky/N//wR13wC9+EfnrhskXAdxai4nyI4ZEJ5GpNJFEimlTqj17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\n",
  140. "text/plain": [
  141. "<Figure size 432x288 with 1 Axes>"
  142. ]
  143. },
  144. "metadata": {
  145. "needs_background": "light"
  146. },
  147. "output_type": "display_data"
  148. }
  149. ],
  150. "source": [
  151. "N = X.shape[0]\n",
  152. "\n",
  153. "S_X2 = np.sum(X*X)\n",
  154. "S_X = np.sum(X)\n",
  155. "S_XY = np.sum(X*Y)\n",
  156. "S_Y = np.sum(Y)\n",
  157. "\n",
  158. "A1 = np.array([[S_X2, S_X], \n",
  159. " [S_X, N]])\n",
  160. "B1 = np.array([S_XY, S_Y])\n",
  161. "\n",
  162. "# numpy.linalg模块包含线性代数的函数。\n",
  163. "# 使用这个模块,可以计算逆矩阵、求特征值、解线性方程组以及求解行列式等。\n",
  164. "coeff = np.linalg.inv(A1).dot(B1)\n",
  165. "\n",
  166. "print('a = %f, b = %f' % (coeff[0], coeff[1]))\n",
  167. "\n",
  168. "x_min = np.min(X)\n",
  169. "x_max = np.max(X)\n",
  170. "y_min = coeff[0] * x_min + coeff[1]\n",
  171. "y_max = coeff[0] * x_max + coeff[1]\n",
  172. "\n",
  173. "plt.scatter(X, Y, label='original data')\n",
  174. "plt.plot([x_min, x_max], [y_min, y_max], 'r', label='model')\n",
  175. "plt.legend()\n",
  176. "plt.show()"
  177. ]
  178. },
  179. {
  180. "cell_type": "markdown",
  181. "metadata": {},
  182. "source": [
  183. "## 2. 如何使用迭代的方法求出模型参数\n",
  184. "\n",
  185. "当数据比较多的时候,或者模型比较复杂,无法直接使用解析的方式求出模型参数。因此更为常用的方式是,通过迭代的方式逐步逼近模型的参数。\n",
  186. "\n",
  187. "### 2.1 梯度下降法\n",
  188. "在机器学习算法中,对于很多监督学习模型,需要对原始的模型构建损失函数,接下来便是通过优化算法对损失函数进行优化,以便寻找到最优的参数。在求解机器学习参数的优化算法中,使用较多的是基于梯度下降的优化算法(Gradient Descent, GD)。\n",
  189. "\n",
  190. "梯度下降法有很多优点,其中最主要的优点是,**在梯度下降法的求解过程中只需求解损失函数的一阶导数,计算的代价比较小,这使得梯度下降法能在很多大规模数据集上得到应用。**\n",
  191. "\n",
  192. "梯度下降法的含义是通过当前点的梯度方向寻找到新的迭代点。梯度下降法的基本思想可以类比为一个下山的过程。假设这样一个场景:\n",
  193. "* 一个人被困在山上,需要从山上下来,找到山的最低点,也就是山谷;\n",
  194. "* 但此时山上的浓雾很大,导致可视度很低。因此,下山的路径就无法全部确定,他必须利用自己周围的信息去找到下山的路径。\n",
  195. "* 以他当前的所处的位置为基准,寻找这个位置最陡峭的地方,然后朝着山的高度下降的地方走\n",
  196. "* 每走一段距离,都反复采用同一个方法,最后就能成功的抵达山谷。\n",
  197. "\n",
  198. "\n",
  199. "一般情况下,这座山最陡峭的地方是无法通过肉眼立马观察出来的,而是需要一个工具来测量;同时,这个人此时正好拥有测量出最陡峭方向的能力。所以,此人每走一段距离,都需要一段时间来测量所在位置最陡峭的方向,这是比较耗时的。那么为了在太阳下山之前到达山底,就要尽可能的减少测量方向的次数。这是一个两难的选择,如果测量的频繁,可以保证下山的方向是绝对正确的,但又非常耗时;如果测量的过少,又有偏离轨道的风险。所以需要找到一个合适的测量方向的频率,来确保下山的方向不错误,同时又不至于耗时太多!\n",
  200. "\n",
  201. "\n",
  202. "![gradient_descent](images/gradient_descent.png)\n",
  203. "\n",
  204. "如上图所示,得到了最优解。$x$,$y$表示的是$\\theta_0$和$\\theta_1$,$z$方向表示的是花费函数,很明显出发点不同,最后到达的收敛点可能不一样。当然如果是碗状的,那么收敛点就应该是一样的。\n",
  205. "\n",
  206. "对于最小二乘的损失函数\n",
  207. "$$\n",
  208. "L = \\sum_{i=1}^{N} (y_i - a x_i - b)^2\n",
  209. "$$\n",
  210. "\n",
  211. "更新的策略是:\n",
  212. "$$\n",
  213. "\\theta^1 = \\theta^0 - \\eta \\triangledown L(\\theta)\n",
  214. "$$\n",
  215. "其中$\\theta$代表了模型中的参数,例如$a$, $b$\n",
  216. "\n",
  217. "此公式的意义是:$L$是关于$\\theta$的一个函数,我们当前所处的位置为$\\theta_0$点,要从这个点走到L的最小值点,也就是山底。首先我们先确定前进的方向,也就是梯度的反向,然后走一段距离的步长,也就是$\\eta$,走完这个段步长,就到达了$\\theta_1$这个点!\n",
  218. "\n",
  219. "最终的更新方程是:\n",
  220. "\n",
  221. "$$\n",
  222. "a^1 = a^0 + 2 \\eta [ y - (ax+b)]*x \\\\\n",
  223. "b^1 = b^0 + 2 \\eta [ y - (ax+b)] \n",
  224. "$$\n",
  225. "\n",
  226. "下面就这个公式的几个常见的疑问:\n",
  227. "\n",
  228. "* **$\\eta$是什么含义?**\n",
  229. "$\\eta$在梯度下降算法中被称作为学习率或者步长,意味着我们可以通过$\\eta$来控制每一步走的距离,以保证不要步子跨的太大,错过了最低点。同时也要保证不要走的太慢,导致太阳下山了,还没有走到山下。所以$\\eta$的选择在梯度下降法中往往是很重要的。\n",
  230. "![gd_stepsize](images/gd_stepsize.png)\n",
  231. "\n",
  232. "* **为什么要梯度要乘以一个负号?**\n",
  233. "梯度前加一个负号,就意味着朝着梯度相反的方向前进!梯度的方向实际就是函数在此点上升最快的方向,而我们需要朝着下降最快的方向走,自然就是负的梯度的方向,所以此处需要加上负号。\n",
  234. "\n"
  235. ]
  236. },
  237. {
  238. "cell_type": "markdown",
  239. "metadata": {},
  240. "source": [
  241. "### 2.2 示例代码"
  242. ]
  243. },
  244. {
  245. "cell_type": "code",
  246. "execution_count": 5,
  247. "metadata": {},
  248. "outputs": [
  249. {
  250. "name": "stdout",
  251. "output_type": "stream",
  252. "text": [
  253. "epoch 0: loss = 964.462432, a = 3.605114, b = 1.371685\n",
  254. "epoch 100: loss = 856.680487, a = 3.044999, b = 3.374801\n",
  255. "epoch 200: loss = 900.182987, a = 3.261635, b = 3.670704\n",
  256. "epoch 300: loss = 841.107710, a = 3.082096, b = 3.703232\n",
  257. "epoch 400: loss = 848.034818, a = 3.023324, b = 3.703601\n"
  258. ]
  259. },
  260. {
  261. "data": {
  262. "image/png": "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\n",
  263. "text/plain": [
  264. "<Figure size 432x288 with 1 Axes>"
  265. ]
  266. },
  267. "metadata": {
  268. "needs_background": "light"
  269. },
  270. "output_type": "display_data"
  271. }
  272. ],
  273. "source": [
  274. "import random\n",
  275. "\n",
  276. "n_epoch = 500 # epoch size\n",
  277. "a, b = 1, 1 # initial parameters\n",
  278. "epsilon = 0.001 # learning rate\n",
  279. "\n",
  280. "for i in range(n_epoch):\n",
  281. " data_idx = list(range(N))\n",
  282. " random.shuffle(data_idx)\n",
  283. " \n",
  284. " for j in data_idx:\n",
  285. " a = a + epsilon*2*(Y[j] - a*X[j] - b)*X[j]\n",
  286. " b = b + epsilon*2*(Y[j] - a*X[j] - b)\n",
  287. "\n",
  288. " L = 0\n",
  289. " for j in range(N):\n",
  290. " L = L + (Y[j]-a*X[j]-b)**2\n",
  291. " \n",
  292. " if i % 100 == 0:\n",
  293. " print(\"epoch %4d: loss = %f, a = %f, b = %f\" % (i, L, a, b))\n",
  294. " \n",
  295. "x_min = np.min(X)\n",
  296. "x_max = np.max(X)\n",
  297. "y_min = a * x_min + b\n",
  298. "y_max = a * x_max + b\n",
  299. "\n",
  300. "plt.scatter(X, Y, label='original data')\n",
  301. "plt.plot([x_min, x_max], [y_min, y_max], 'r', label='model')\n",
  302. "plt.legend()\n",
  303. "plt.show()"
  304. ]
  305. },
  306. {
  307. "cell_type": "markdown",
  308. "metadata": {},
  309. "source": [
  310. "## 3. 如何可视化迭代过程"
  311. ]
  312. },
  313. {
  314. "cell_type": "code",
  315. "execution_count": 6,
  316. "metadata": {},
  317. "outputs": [
  318. {
  319. "data": {
  320. "application/javascript": [
  321. "/* Put everything inside the global mpl namespace */\n",
  322. "/* global mpl */\n",
  323. "window.mpl = {};\n",
  324. "\n",
  325. "mpl.get_websocket_type = function () {\n",
  326. " if (typeof WebSocket !== 'undefined') {\n",
  327. " return WebSocket;\n",
  328. " } else if (typeof MozWebSocket !== 'undefined') {\n",
  329. " return MozWebSocket;\n",
  330. " } else {\n",
  331. " alert(\n",
  332. " 'Your browser does not have WebSocket support. ' +\n",
  333. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  334. " 'Firefox 4 and 5 are also supported but you ' +\n",
  335. " 'have to enable WebSockets in about:config.'\n",
  336. " );\n",
  337. " }\n",
  338. "};\n",
  339. "\n",
  340. "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
  341. " this.id = figure_id;\n",
  342. "\n",
  343. " this.ws = websocket;\n",
  344. "\n",
  345. " this.supports_binary = this.ws.binaryType !== undefined;\n",
  346. "\n",
  347. " if (!this.supports_binary) {\n",
  348. " var warnings = document.getElementById('mpl-warnings');\n",
  349. " if (warnings) {\n",
  350. " warnings.style.display = 'block';\n",
  351. " warnings.textContent =\n",
  352. " 'This browser does not support binary websocket messages. ' +\n",
  353. " 'Performance may be slow.';\n",
  354. " }\n",
  355. " }\n",
  356. "\n",
  357. " this.imageObj = new Image();\n",
  358. "\n",
  359. " this.context = undefined;\n",
  360. " this.message = undefined;\n",
  361. " this.canvas = undefined;\n",
  362. " this.rubberband_canvas = undefined;\n",
  363. " this.rubberband_context = undefined;\n",
  364. " this.format_dropdown = undefined;\n",
  365. "\n",
  366. " this.image_mode = 'full';\n",
  367. "\n",
  368. " this.root = document.createElement('div');\n",
  369. " this.root.setAttribute('style', 'display: inline-block');\n",
  370. " this._root_extra_style(this.root);\n",
  371. "\n",
  372. " parent_element.appendChild(this.root);\n",
  373. "\n",
  374. " this._init_header(this);\n",
  375. " this._init_canvas(this);\n",
  376. " this._init_toolbar(this);\n",
  377. "\n",
  378. " var fig = this;\n",
  379. "\n",
  380. " this.waiting = false;\n",
  381. "\n",
  382. " this.ws.onopen = function () {\n",
  383. " fig.send_message('supports_binary', { value: fig.supports_binary });\n",
  384. " fig.send_message('send_image_mode', {});\n",
  385. " if (fig.ratio !== 1) {\n",
  386. " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n",
  387. " }\n",
  388. " fig.send_message('refresh', {});\n",
  389. " };\n",
  390. "\n",
  391. " this.imageObj.onload = function () {\n",
  392. " if (fig.image_mode === 'full') {\n",
  393. " // Full images could contain transparency (where diff images\n",
  394. " // almost always do), so we need to clear the canvas so that\n",
  395. " // there is no ghosting.\n",
  396. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  397. " }\n",
  398. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  399. " };\n",
  400. "\n",
  401. " this.imageObj.onunload = function () {\n",
  402. " fig.ws.close();\n",
  403. " };\n",
  404. "\n",
  405. " this.ws.onmessage = this._make_on_message_function(this);\n",
  406. "\n",
  407. " this.ondownload = ondownload;\n",
  408. "};\n",
  409. "\n",
  410. "mpl.figure.prototype._init_header = function () {\n",
  411. " var titlebar = document.createElement('div');\n",
  412. " titlebar.classList =\n",
  413. " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
  414. " var titletext = document.createElement('div');\n",
  415. " titletext.classList = 'ui-dialog-title';\n",
  416. " titletext.setAttribute(\n",
  417. " 'style',\n",
  418. " 'width: 100%; text-align: center; padding: 3px;'\n",
  419. " );\n",
  420. " titlebar.appendChild(titletext);\n",
  421. " this.root.appendChild(titlebar);\n",
  422. " this.header = titletext;\n",
  423. "};\n",
  424. "\n",
  425. "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
  426. "\n",
  427. "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
  428. "\n",
  429. "mpl.figure.prototype._init_canvas = function () {\n",
  430. " var fig = this;\n",
  431. "\n",
  432. " var canvas_div = (this.canvas_div = document.createElement('div'));\n",
  433. " canvas_div.setAttribute(\n",
  434. " 'style',\n",
  435. " 'border: 1px solid #ddd;' +\n",
  436. " 'box-sizing: content-box;' +\n",
  437. " 'clear: both;' +\n",
  438. " 'min-height: 1px;' +\n",
  439. " 'min-width: 1px;' +\n",
  440. " 'outline: 0;' +\n",
  441. " 'overflow: hidden;' +\n",
  442. " 'position: relative;' +\n",
  443. " 'resize: both;'\n",
  444. " );\n",
  445. "\n",
  446. " function on_keyboard_event_closure(name) {\n",
  447. " return function (event) {\n",
  448. " return fig.key_event(event, name);\n",
  449. " };\n",
  450. " }\n",
  451. "\n",
  452. " canvas_div.addEventListener(\n",
  453. " 'keydown',\n",
  454. " on_keyboard_event_closure('key_press')\n",
  455. " );\n",
  456. " canvas_div.addEventListener(\n",
  457. " 'keyup',\n",
  458. " on_keyboard_event_closure('key_release')\n",
  459. " );\n",
  460. "\n",
  461. " this._canvas_extra_style(canvas_div);\n",
  462. " this.root.appendChild(canvas_div);\n",
  463. "\n",
  464. " var canvas = (this.canvas = document.createElement('canvas'));\n",
  465. " canvas.classList.add('mpl-canvas');\n",
  466. " canvas.setAttribute('style', 'box-sizing: content-box;');\n",
  467. "\n",
  468. " this.context = canvas.getContext('2d');\n",
  469. "\n",
  470. " var backingStore =\n",
  471. " this.context.backingStorePixelRatio ||\n",
  472. " this.context.webkitBackingStorePixelRatio ||\n",
  473. " this.context.mozBackingStorePixelRatio ||\n",
  474. " this.context.msBackingStorePixelRatio ||\n",
  475. " this.context.oBackingStorePixelRatio ||\n",
  476. " this.context.backingStorePixelRatio ||\n",
  477. " 1;\n",
  478. "\n",
  479. " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  480. "\n",
  481. " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
  482. " 'canvas'\n",
  483. " ));\n",
  484. " rubberband_canvas.setAttribute(\n",
  485. " 'style',\n",
  486. " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
  487. " );\n",
  488. "\n",
  489. " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
  490. " if (this.ResizeObserver === undefined) {\n",
  491. " if (window.ResizeObserver !== undefined) {\n",
  492. " this.ResizeObserver = window.ResizeObserver;\n",
  493. " } else {\n",
  494. " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
  495. " this.ResizeObserver = obs.ResizeObserver;\n",
  496. " }\n",
  497. " }\n",
  498. "\n",
  499. " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
  500. " var nentries = entries.length;\n",
  501. " for (var i = 0; i < nentries; i++) {\n",
  502. " var entry = entries[i];\n",
  503. " var width, height;\n",
  504. " if (entry.contentBoxSize) {\n",
  505. " if (entry.contentBoxSize instanceof Array) {\n",
  506. " // Chrome 84 implements new version of spec.\n",
  507. " width = entry.contentBoxSize[0].inlineSize;\n",
  508. " height = entry.contentBoxSize[0].blockSize;\n",
  509. " } else {\n",
  510. " // Firefox implements old version of spec.\n",
  511. " width = entry.contentBoxSize.inlineSize;\n",
  512. " height = entry.contentBoxSize.blockSize;\n",
  513. " }\n",
  514. " } else {\n",
  515. " // Chrome <84 implements even older version of spec.\n",
  516. " width = entry.contentRect.width;\n",
  517. " height = entry.contentRect.height;\n",
  518. " }\n",
  519. "\n",
  520. " // Keep the size of the canvas and rubber band canvas in sync with\n",
  521. " // the canvas container.\n",
  522. " if (entry.devicePixelContentBoxSize) {\n",
  523. " // Chrome 84 implements new version of spec.\n",
  524. " canvas.setAttribute(\n",
  525. " 'width',\n",
  526. " entry.devicePixelContentBoxSize[0].inlineSize\n",
  527. " );\n",
  528. " canvas.setAttribute(\n",
  529. " 'height',\n",
  530. " entry.devicePixelContentBoxSize[0].blockSize\n",
  531. " );\n",
  532. " } else {\n",
  533. " canvas.setAttribute('width', width * fig.ratio);\n",
  534. " canvas.setAttribute('height', height * fig.ratio);\n",
  535. " }\n",
  536. " canvas.setAttribute(\n",
  537. " 'style',\n",
  538. " 'width: ' + width + 'px; height: ' + height + 'px;'\n",
  539. " );\n",
  540. "\n",
  541. " rubberband_canvas.setAttribute('width', width);\n",
  542. " rubberband_canvas.setAttribute('height', height);\n",
  543. "\n",
  544. " // And update the size in Python. We ignore the initial 0/0 size\n",
  545. " // that occurs as the element is placed into the DOM, which should\n",
  546. " // otherwise not happen due to the minimum size styling.\n",
  547. " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
  548. " fig.request_resize(width, height);\n",
  549. " }\n",
  550. " }\n",
  551. " });\n",
  552. " this.resizeObserverInstance.observe(canvas_div);\n",
  553. "\n",
  554. " function on_mouse_event_closure(name) {\n",
  555. " return function (event) {\n",
  556. " return fig.mouse_event(event, name);\n",
  557. " };\n",
  558. " }\n",
  559. "\n",
  560. " rubberband_canvas.addEventListener(\n",
  561. " 'mousedown',\n",
  562. " on_mouse_event_closure('button_press')\n",
  563. " );\n",
  564. " rubberband_canvas.addEventListener(\n",
  565. " 'mouseup',\n",
  566. " on_mouse_event_closure('button_release')\n",
  567. " );\n",
  568. " rubberband_canvas.addEventListener(\n",
  569. " 'dblclick',\n",
  570. " on_mouse_event_closure('dblclick')\n",
  571. " );\n",
  572. " // Throttle sequential mouse events to 1 every 20ms.\n",
  573. " rubberband_canvas.addEventListener(\n",
  574. " 'mousemove',\n",
  575. " on_mouse_event_closure('motion_notify')\n",
  576. " );\n",
  577. "\n",
  578. " rubberband_canvas.addEventListener(\n",
  579. " 'mouseenter',\n",
  580. " on_mouse_event_closure('figure_enter')\n",
  581. " );\n",
  582. " rubberband_canvas.addEventListener(\n",
  583. " 'mouseleave',\n",
  584. " on_mouse_event_closure('figure_leave')\n",
  585. " );\n",
  586. "\n",
  587. " canvas_div.addEventListener('wheel', function (event) {\n",
  588. " if (event.deltaY < 0) {\n",
  589. " event.step = 1;\n",
  590. " } else {\n",
  591. " event.step = -1;\n",
  592. " }\n",
  593. " on_mouse_event_closure('scroll')(event);\n",
  594. " });\n",
  595. "\n",
  596. " canvas_div.appendChild(canvas);\n",
  597. " canvas_div.appendChild(rubberband_canvas);\n",
  598. "\n",
  599. " this.rubberband_context = rubberband_canvas.getContext('2d');\n",
  600. " this.rubberband_context.strokeStyle = '#000000';\n",
  601. "\n",
  602. " this._resize_canvas = function (width, height, forward) {\n",
  603. " if (forward) {\n",
  604. " canvas_div.style.width = width + 'px';\n",
  605. " canvas_div.style.height = height + 'px';\n",
  606. " }\n",
  607. " };\n",
  608. "\n",
  609. " // Disable right mouse context menu.\n",
  610. " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
  611. " event.preventDefault();\n",
  612. " return false;\n",
  613. " });\n",
  614. "\n",
  615. " function set_focus() {\n",
  616. " canvas.focus();\n",
  617. " canvas_div.focus();\n",
  618. " }\n",
  619. "\n",
  620. " window.setTimeout(set_focus, 100);\n",
  621. "};\n",
  622. "\n",
  623. "mpl.figure.prototype._init_toolbar = function () {\n",
  624. " var fig = this;\n",
  625. "\n",
  626. " var toolbar = document.createElement('div');\n",
  627. " toolbar.classList = 'mpl-toolbar';\n",
  628. " this.root.appendChild(toolbar);\n",
  629. "\n",
  630. " function on_click_closure(name) {\n",
  631. " return function (_event) {\n",
  632. " return fig.toolbar_button_onclick(name);\n",
  633. " };\n",
  634. " }\n",
  635. "\n",
  636. " function on_mouseover_closure(tooltip) {\n",
  637. " return function (event) {\n",
  638. " if (!event.currentTarget.disabled) {\n",
  639. " return fig.toolbar_button_onmouseover(tooltip);\n",
  640. " }\n",
  641. " };\n",
  642. " }\n",
  643. "\n",
  644. " fig.buttons = {};\n",
  645. " var buttonGroup = document.createElement('div');\n",
  646. " buttonGroup.classList = 'mpl-button-group';\n",
  647. " for (var toolbar_ind in mpl.toolbar_items) {\n",
  648. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  649. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  650. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  651. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  652. "\n",
  653. " if (!name) {\n",
  654. " /* Instead of a spacer, we start a new button group. */\n",
  655. " if (buttonGroup.hasChildNodes()) {\n",
  656. " toolbar.appendChild(buttonGroup);\n",
  657. " }\n",
  658. " buttonGroup = document.createElement('div');\n",
  659. " buttonGroup.classList = 'mpl-button-group';\n",
  660. " continue;\n",
  661. " }\n",
  662. "\n",
  663. " var button = (fig.buttons[name] = document.createElement('button'));\n",
  664. " button.classList = 'mpl-widget';\n",
  665. " button.setAttribute('role', 'button');\n",
  666. " button.setAttribute('aria-disabled', 'false');\n",
  667. " button.addEventListener('click', on_click_closure(method_name));\n",
  668. " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
  669. "\n",
  670. " var icon_img = document.createElement('img');\n",
  671. " icon_img.src = '_images/' + image + '.png';\n",
  672. " icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
  673. " icon_img.alt = tooltip;\n",
  674. " button.appendChild(icon_img);\n",
  675. "\n",
  676. " buttonGroup.appendChild(button);\n",
  677. " }\n",
  678. "\n",
  679. " if (buttonGroup.hasChildNodes()) {\n",
  680. " toolbar.appendChild(buttonGroup);\n",
  681. " }\n",
  682. "\n",
  683. " var fmt_picker = document.createElement('select');\n",
  684. " fmt_picker.classList = 'mpl-widget';\n",
  685. " toolbar.appendChild(fmt_picker);\n",
  686. " this.format_dropdown = fmt_picker;\n",
  687. "\n",
  688. " for (var ind in mpl.extensions) {\n",
  689. " var fmt = mpl.extensions[ind];\n",
  690. " var option = document.createElement('option');\n",
  691. " option.selected = fmt === mpl.default_extension;\n",
  692. " option.innerHTML = fmt;\n",
  693. " fmt_picker.appendChild(option);\n",
  694. " }\n",
  695. "\n",
  696. " var status_bar = document.createElement('span');\n",
  697. " status_bar.classList = 'mpl-message';\n",
  698. " toolbar.appendChild(status_bar);\n",
  699. " this.message = status_bar;\n",
  700. "};\n",
  701. "\n",
  702. "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
  703. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  704. " // which will in turn request a refresh of the image.\n",
  705. " this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
  706. "};\n",
  707. "\n",
  708. "mpl.figure.prototype.send_message = function (type, properties) {\n",
  709. " properties['type'] = type;\n",
  710. " properties['figure_id'] = this.id;\n",
  711. " this.ws.send(JSON.stringify(properties));\n",
  712. "};\n",
  713. "\n",
  714. "mpl.figure.prototype.send_draw_message = function () {\n",
  715. " if (!this.waiting) {\n",
  716. " this.waiting = true;\n",
  717. " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
  718. " }\n",
  719. "};\n",
  720. "\n",
  721. "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
  722. " var format_dropdown = fig.format_dropdown;\n",
  723. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  724. " fig.ondownload(fig, format);\n",
  725. "};\n",
  726. "\n",
  727. "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
  728. " var size = msg['size'];\n",
  729. " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
  730. " fig._resize_canvas(size[0], size[1], msg['forward']);\n",
  731. " fig.send_message('refresh', {});\n",
  732. " }\n",
  733. "};\n",
  734. "\n",
  735. "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
  736. " var x0 = msg['x0'] / fig.ratio;\n",
  737. " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
  738. " var x1 = msg['x1'] / fig.ratio;\n",
  739. " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
  740. " x0 = Math.floor(x0) + 0.5;\n",
  741. " y0 = Math.floor(y0) + 0.5;\n",
  742. " x1 = Math.floor(x1) + 0.5;\n",
  743. " y1 = Math.floor(y1) + 0.5;\n",
  744. " var min_x = Math.min(x0, x1);\n",
  745. " var min_y = Math.min(y0, y1);\n",
  746. " var width = Math.abs(x1 - x0);\n",
  747. " var height = Math.abs(y1 - y0);\n",
  748. "\n",
  749. " fig.rubberband_context.clearRect(\n",
  750. " 0,\n",
  751. " 0,\n",
  752. " fig.canvas.width / fig.ratio,\n",
  753. " fig.canvas.height / fig.ratio\n",
  754. " );\n",
  755. "\n",
  756. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  757. "};\n",
  758. "\n",
  759. "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
  760. " // Updates the figure title.\n",
  761. " fig.header.textContent = msg['label'];\n",
  762. "};\n",
  763. "\n",
  764. "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
  765. " var cursor = msg['cursor'];\n",
  766. " switch (cursor) {\n",
  767. " case 0:\n",
  768. " cursor = 'pointer';\n",
  769. " break;\n",
  770. " case 1:\n",
  771. " cursor = 'default';\n",
  772. " break;\n",
  773. " case 2:\n",
  774. " cursor = 'crosshair';\n",
  775. " break;\n",
  776. " case 3:\n",
  777. " cursor = 'move';\n",
  778. " break;\n",
  779. " }\n",
  780. " fig.rubberband_canvas.style.cursor = cursor;\n",
  781. "};\n",
  782. "\n",
  783. "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
  784. " fig.message.textContent = msg['message'];\n",
  785. "};\n",
  786. "\n",
  787. "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
  788. " // Request the server to send over a new figure.\n",
  789. " fig.send_draw_message();\n",
  790. "};\n",
  791. "\n",
  792. "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
  793. " fig.image_mode = msg['mode'];\n",
  794. "};\n",
  795. "\n",
  796. "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
  797. " for (var key in msg) {\n",
  798. " if (!(key in fig.buttons)) {\n",
  799. " continue;\n",
  800. " }\n",
  801. " fig.buttons[key].disabled = !msg[key];\n",
  802. " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
  803. " }\n",
  804. "};\n",
  805. "\n",
  806. "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
  807. " if (msg['mode'] === 'PAN') {\n",
  808. " fig.buttons['Pan'].classList.add('active');\n",
  809. " fig.buttons['Zoom'].classList.remove('active');\n",
  810. " } else if (msg['mode'] === 'ZOOM') {\n",
  811. " fig.buttons['Pan'].classList.remove('active');\n",
  812. " fig.buttons['Zoom'].classList.add('active');\n",
  813. " } else {\n",
  814. " fig.buttons['Pan'].classList.remove('active');\n",
  815. " fig.buttons['Zoom'].classList.remove('active');\n",
  816. " }\n",
  817. "};\n",
  818. "\n",
  819. "mpl.figure.prototype.updated_canvas_event = function () {\n",
  820. " // Called whenever the canvas gets updated.\n",
  821. " this.send_message('ack', {});\n",
  822. "};\n",
  823. "\n",
  824. "// A function to construct a web socket function for onmessage handling.\n",
  825. "// Called in the figure constructor.\n",
  826. "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
  827. " return function socket_on_message(evt) {\n",
  828. " if (evt.data instanceof Blob) {\n",
  829. " var img = evt.data;\n",
  830. " if (img.type !== 'image/png') {\n",
  831. " /* FIXME: We get \"Resource interpreted as Image but\n",
  832. " * transferred with MIME type text/plain:\" errors on\n",
  833. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  834. " * to be part of the websocket stream */\n",
  835. " img.type = 'image/png';\n",
  836. " }\n",
  837. "\n",
  838. " /* Free the memory for the previous frames */\n",
  839. " if (fig.imageObj.src) {\n",
  840. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  841. " fig.imageObj.src\n",
  842. " );\n",
  843. " }\n",
  844. "\n",
  845. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  846. " img\n",
  847. " );\n",
  848. " fig.updated_canvas_event();\n",
  849. " fig.waiting = false;\n",
  850. " return;\n",
  851. " } else if (\n",
  852. " typeof evt.data === 'string' &&\n",
  853. " evt.data.slice(0, 21) === 'data:image/png;base64'\n",
  854. " ) {\n",
  855. " fig.imageObj.src = evt.data;\n",
  856. " fig.updated_canvas_event();\n",
  857. " fig.waiting = false;\n",
  858. " return;\n",
  859. " }\n",
  860. "\n",
  861. " var msg = JSON.parse(evt.data);\n",
  862. " var msg_type = msg['type'];\n",
  863. "\n",
  864. " // Call the \"handle_{type}\" callback, which takes\n",
  865. " // the figure and JSON message as its only arguments.\n",
  866. " try {\n",
  867. " var callback = fig['handle_' + msg_type];\n",
  868. " } catch (e) {\n",
  869. " console.log(\n",
  870. " \"No handler for the '\" + msg_type + \"' message type: \",\n",
  871. " msg\n",
  872. " );\n",
  873. " return;\n",
  874. " }\n",
  875. "\n",
  876. " if (callback) {\n",
  877. " try {\n",
  878. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  879. " callback(fig, msg);\n",
  880. " } catch (e) {\n",
  881. " console.log(\n",
  882. " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
  883. " e,\n",
  884. " e.stack,\n",
  885. " msg\n",
  886. " );\n",
  887. " }\n",
  888. " }\n",
  889. " };\n",
  890. "};\n",
  891. "\n",
  892. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  893. "mpl.findpos = function (e) {\n",
  894. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  895. " var targ;\n",
  896. " if (!e) {\n",
  897. " e = window.event;\n",
  898. " }\n",
  899. " if (e.target) {\n",
  900. " targ = e.target;\n",
  901. " } else if (e.srcElement) {\n",
  902. " targ = e.srcElement;\n",
  903. " }\n",
  904. " if (targ.nodeType === 3) {\n",
  905. " // defeat Safari bug\n",
  906. " targ = targ.parentNode;\n",
  907. " }\n",
  908. "\n",
  909. " // pageX,Y are the mouse positions relative to the document\n",
  910. " var boundingRect = targ.getBoundingClientRect();\n",
  911. " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
  912. " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
  913. "\n",
  914. " return { x: x, y: y };\n",
  915. "};\n",
  916. "\n",
  917. "/*\n",
  918. " * return a copy of an object with only non-object keys\n",
  919. " * we need this to avoid circular references\n",
  920. " * http://stackoverflow.com/a/24161582/3208463\n",
  921. " */\n",
  922. "function simpleKeys(original) {\n",
  923. " return Object.keys(original).reduce(function (obj, key) {\n",
  924. " if (typeof original[key] !== 'object') {\n",
  925. " obj[key] = original[key];\n",
  926. " }\n",
  927. " return obj;\n",
  928. " }, {});\n",
  929. "}\n",
  930. "\n",
  931. "mpl.figure.prototype.mouse_event = function (event, name) {\n",
  932. " var canvas_pos = mpl.findpos(event);\n",
  933. "\n",
  934. " if (name === 'button_press') {\n",
  935. " this.canvas.focus();\n",
  936. " this.canvas_div.focus();\n",
  937. " }\n",
  938. "\n",
  939. " var x = canvas_pos.x * this.ratio;\n",
  940. " var y = canvas_pos.y * this.ratio;\n",
  941. "\n",
  942. " this.send_message(name, {\n",
  943. " x: x,\n",
  944. " y: y,\n",
  945. " button: event.button,\n",
  946. " step: event.step,\n",
  947. " guiEvent: simpleKeys(event),\n",
  948. " });\n",
  949. "\n",
  950. " /* This prevents the web browser from automatically changing to\n",
  951. " * the text insertion cursor when the button is pressed. We want\n",
  952. " * to control all of the cursor setting manually through the\n",
  953. " * 'cursor' event from matplotlib */\n",
  954. " event.preventDefault();\n",
  955. " return false;\n",
  956. "};\n",
  957. "\n",
  958. "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
  959. " // Handle any extra behaviour associated with a key event\n",
  960. "};\n",
  961. "\n",
  962. "mpl.figure.prototype.key_event = function (event, name) {\n",
  963. " // Prevent repeat events\n",
  964. " if (name === 'key_press') {\n",
  965. " if (event.key === this._key) {\n",
  966. " return;\n",
  967. " } else {\n",
  968. " this._key = event.key;\n",
  969. " }\n",
  970. " }\n",
  971. " if (name === 'key_release') {\n",
  972. " this._key = null;\n",
  973. " }\n",
  974. "\n",
  975. " var value = '';\n",
  976. " if (event.ctrlKey && event.key !== 'Control') {\n",
  977. " value += 'ctrl+';\n",
  978. " }\n",
  979. " else if (event.altKey && event.key !== 'Alt') {\n",
  980. " value += 'alt+';\n",
  981. " }\n",
  982. " else if (event.shiftKey && event.key !== 'Shift') {\n",
  983. " value += 'shift+';\n",
  984. " }\n",
  985. "\n",
  986. " value += 'k' + event.key;\n",
  987. "\n",
  988. " this._key_event_extra(event, name);\n",
  989. "\n",
  990. " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
  991. " return false;\n",
  992. "};\n",
  993. "\n",
  994. "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
  995. " if (name === 'download') {\n",
  996. " this.handle_save(this, null);\n",
  997. " } else {\n",
  998. " this.send_message('toolbar_button', { name: name });\n",
  999. " }\n",
  1000. "};\n",
  1001. "\n",
  1002. "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
  1003. " this.message.textContent = tooltip;\n",
  1004. "};\n",
  1005. "\n",
  1006. "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
  1007. "// prettier-ignore\n",
  1008. "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",
  1009. "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, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  1010. "\n",
  1011. "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  1012. "\n",
  1013. "mpl.default_extension = \"png\";/* global mpl */\n",
  1014. "\n",
  1015. "var comm_websocket_adapter = function (comm) {\n",
  1016. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  1017. " // object with the appropriate methods. Currently this is a non binary\n",
  1018. " // socket, so there is still some room for performance tuning.\n",
  1019. " var ws = {};\n",
  1020. "\n",
  1021. " ws.binaryType = comm.kernel.ws.binaryType;\n",
  1022. " ws.readyState = comm.kernel.ws.readyState;\n",
  1023. " function updateReadyState(_event) {\n",
  1024. " if (comm.kernel.ws) {\n",
  1025. " ws.readyState = comm.kernel.ws.readyState;\n",
  1026. " } else {\n",
  1027. " ws.readyState = 3; // Closed state.\n",
  1028. " }\n",
  1029. " }\n",
  1030. " comm.kernel.ws.addEventListener('open', updateReadyState);\n",
  1031. " comm.kernel.ws.addEventListener('close', updateReadyState);\n",
  1032. " comm.kernel.ws.addEventListener('error', updateReadyState);\n",
  1033. "\n",
  1034. " ws.close = function () {\n",
  1035. " comm.close();\n",
  1036. " };\n",
  1037. " ws.send = function (m) {\n",
  1038. " //console.log('sending', m);\n",
  1039. " comm.send(m);\n",
  1040. " };\n",
  1041. " // Register the callback with on_msg.\n",
  1042. " comm.on_msg(function (msg) {\n",
  1043. " //console.log('receiving', msg['content']['data'], msg);\n",
  1044. " var data = msg['content']['data'];\n",
  1045. " if (data['blob'] !== undefined) {\n",
  1046. " data = {\n",
  1047. " data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
  1048. " };\n",
  1049. " }\n",
  1050. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  1051. " ws.onmessage(data);\n",
  1052. " });\n",
  1053. " return ws;\n",
  1054. "};\n",
  1055. "\n",
  1056. "mpl.mpl_figure_comm = function (comm, msg) {\n",
  1057. " // This is the function which gets called when the mpl process\n",
  1058. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  1059. "\n",
  1060. " var id = msg.content.data.id;\n",
  1061. " // Get hold of the div created by the display call when the Comm\n",
  1062. " // socket was opened in Python.\n",
  1063. " var element = document.getElementById(id);\n",
  1064. " var ws_proxy = comm_websocket_adapter(comm);\n",
  1065. "\n",
  1066. " function ondownload(figure, _format) {\n",
  1067. " window.open(figure.canvas.toDataURL());\n",
  1068. " }\n",
  1069. "\n",
  1070. " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
  1071. "\n",
  1072. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  1073. " // web socket which is closed, not our websocket->open comm proxy.\n",
  1074. " ws_proxy.onopen();\n",
  1075. "\n",
  1076. " fig.parent_element = element;\n",
  1077. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  1078. " if (!fig.cell_info) {\n",
  1079. " console.error('Failed to find cell for figure', id, fig);\n",
  1080. " return;\n",
  1081. " }\n",
  1082. " fig.cell_info[0].output_area.element.on(\n",
  1083. " 'cleared',\n",
  1084. " { fig: fig },\n",
  1085. " fig._remove_fig_handler\n",
  1086. " );\n",
  1087. "};\n",
  1088. "\n",
  1089. "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
  1090. " var width = fig.canvas.width / fig.ratio;\n",
  1091. " fig.cell_info[0].output_area.element.off(\n",
  1092. " 'cleared',\n",
  1093. " fig._remove_fig_handler\n",
  1094. " );\n",
  1095. " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
  1096. "\n",
  1097. " // Update the output cell to use the data from the current canvas.\n",
  1098. " fig.push_to_output();\n",
  1099. " var dataURL = fig.canvas.toDataURL();\n",
  1100. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  1101. " // the notebook keyboard shortcuts fail.\n",
  1102. " IPython.keyboard_manager.enable();\n",
  1103. " fig.parent_element.innerHTML =\n",
  1104. " '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  1105. " fig.close_ws(fig, msg);\n",
  1106. "};\n",
  1107. "\n",
  1108. "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
  1109. " fig.send_message('closing', msg);\n",
  1110. " // fig.ws.close()\n",
  1111. "};\n",
  1112. "\n",
  1113. "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
  1114. " // Turn the data on the canvas into data in the output cell.\n",
  1115. " var width = this.canvas.width / this.ratio;\n",
  1116. " var dataURL = this.canvas.toDataURL();\n",
  1117. " this.cell_info[1]['text/html'] =\n",
  1118. " '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  1119. "};\n",
  1120. "\n",
  1121. "mpl.figure.prototype.updated_canvas_event = function () {\n",
  1122. " // Tell IPython that the notebook contents must change.\n",
  1123. " IPython.notebook.set_dirty(true);\n",
  1124. " this.send_message('ack', {});\n",
  1125. " var fig = this;\n",
  1126. " // Wait a second, then push the new image to the DOM so\n",
  1127. " // that it is saved nicely (might be nice to debounce this).\n",
  1128. " setTimeout(function () {\n",
  1129. " fig.push_to_output();\n",
  1130. " }, 1000);\n",
  1131. "};\n",
  1132. "\n",
  1133. "mpl.figure.prototype._init_toolbar = function () {\n",
  1134. " var fig = this;\n",
  1135. "\n",
  1136. " var toolbar = document.createElement('div');\n",
  1137. " toolbar.classList = 'btn-toolbar';\n",
  1138. " this.root.appendChild(toolbar);\n",
  1139. "\n",
  1140. " function on_click_closure(name) {\n",
  1141. " return function (_event) {\n",
  1142. " return fig.toolbar_button_onclick(name);\n",
  1143. " };\n",
  1144. " }\n",
  1145. "\n",
  1146. " function on_mouseover_closure(tooltip) {\n",
  1147. " return function (event) {\n",
  1148. " if (!event.currentTarget.disabled) {\n",
  1149. " return fig.toolbar_button_onmouseover(tooltip);\n",
  1150. " }\n",
  1151. " };\n",
  1152. " }\n",
  1153. "\n",
  1154. " fig.buttons = {};\n",
  1155. " var buttonGroup = document.createElement('div');\n",
  1156. " buttonGroup.classList = 'btn-group';\n",
  1157. " var button;\n",
  1158. " for (var toolbar_ind in mpl.toolbar_items) {\n",
  1159. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  1160. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  1161. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  1162. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  1163. "\n",
  1164. " if (!name) {\n",
  1165. " /* Instead of a spacer, we start a new button group. */\n",
  1166. " if (buttonGroup.hasChildNodes()) {\n",
  1167. " toolbar.appendChild(buttonGroup);\n",
  1168. " }\n",
  1169. " buttonGroup = document.createElement('div');\n",
  1170. " buttonGroup.classList = 'btn-group';\n",
  1171. " continue;\n",
  1172. " }\n",
  1173. "\n",
  1174. " button = fig.buttons[name] = document.createElement('button');\n",
  1175. " button.classList = 'btn btn-default';\n",
  1176. " button.href = '#';\n",
  1177. " button.title = name;\n",
  1178. " button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
  1179. " button.addEventListener('click', on_click_closure(method_name));\n",
  1180. " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
  1181. " buttonGroup.appendChild(button);\n",
  1182. " }\n",
  1183. "\n",
  1184. " if (buttonGroup.hasChildNodes()) {\n",
  1185. " toolbar.appendChild(buttonGroup);\n",
  1186. " }\n",
  1187. "\n",
  1188. " // Add the status bar.\n",
  1189. " var status_bar = document.createElement('span');\n",
  1190. " status_bar.classList = 'mpl-message pull-right';\n",
  1191. " toolbar.appendChild(status_bar);\n",
  1192. " this.message = status_bar;\n",
  1193. "\n",
  1194. " // Add the close button to the window.\n",
  1195. " var buttongrp = document.createElement('div');\n",
  1196. " buttongrp.classList = 'btn-group inline pull-right';\n",
  1197. " button = document.createElement('button');\n",
  1198. " button.classList = 'btn btn-mini btn-primary';\n",
  1199. " button.href = '#';\n",
  1200. " button.title = 'Stop Interaction';\n",
  1201. " button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
  1202. " button.addEventListener('click', function (_evt) {\n",
  1203. " fig.handle_close(fig, {});\n",
  1204. " });\n",
  1205. " button.addEventListener(\n",
  1206. " 'mouseover',\n",
  1207. " on_mouseover_closure('Stop Interaction')\n",
  1208. " );\n",
  1209. " buttongrp.appendChild(button);\n",
  1210. " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
  1211. " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
  1212. "};\n",
  1213. "\n",
  1214. "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
  1215. " var fig = event.data.fig;\n",
  1216. " if (event.target !== this) {\n",
  1217. " // Ignore bubbled events from children.\n",
  1218. " return;\n",
  1219. " }\n",
  1220. " fig.close_ws(fig, {});\n",
  1221. "};\n",
  1222. "\n",
  1223. "mpl.figure.prototype._root_extra_style = function (el) {\n",
  1224. " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
  1225. "};\n",
  1226. "\n",
  1227. "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
  1228. " // this is important to make the div 'focusable\n",
  1229. " el.setAttribute('tabindex', 0);\n",
  1230. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  1231. " // off when our div gets focus\n",
  1232. "\n",
  1233. " // location in version 3\n",
  1234. " if (IPython.notebook.keyboard_manager) {\n",
  1235. " IPython.notebook.keyboard_manager.register_events(el);\n",
  1236. " } else {\n",
  1237. " // location in version 2\n",
  1238. " IPython.keyboard_manager.register_events(el);\n",
  1239. " }\n",
  1240. "};\n",
  1241. "\n",
  1242. "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
  1243. " var manager = IPython.notebook.keyboard_manager;\n",
  1244. " if (!manager) {\n",
  1245. " manager = IPython.keyboard_manager;\n",
  1246. " }\n",
  1247. "\n",
  1248. " // Check for shift+enter\n",
  1249. " if (event.shiftKey && event.which === 13) {\n",
  1250. " this.canvas_div.blur();\n",
  1251. " // select the cell after this one\n",
  1252. " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
  1253. " IPython.notebook.select(index + 1);\n",
  1254. " }\n",
  1255. "};\n",
  1256. "\n",
  1257. "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
  1258. " fig.ondownload(fig, null);\n",
  1259. "};\n",
  1260. "\n",
  1261. "mpl.find_output_cell = function (html_output) {\n",
  1262. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  1263. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  1264. " // IPython event is triggered only after the cells have been serialised, which for\n",
  1265. " // our purposes (turning an active figure into a static one), is too late.\n",
  1266. " var cells = IPython.notebook.get_cells();\n",
  1267. " var ncells = cells.length;\n",
  1268. " for (var i = 0; i < ncells; i++) {\n",
  1269. " var cell = cells[i];\n",
  1270. " if (cell.cell_type === 'code') {\n",
  1271. " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
  1272. " var data = cell.output_area.outputs[j];\n",
  1273. " if (data.data) {\n",
  1274. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  1275. " data = data.data;\n",
  1276. " }\n",
  1277. " if (data['text/html'] === html_output) {\n",
  1278. " return [cell, data, j];\n",
  1279. " }\n",
  1280. " }\n",
  1281. " }\n",
  1282. " }\n",
  1283. "};\n",
  1284. "\n",
  1285. "// Register the function which deals with the matplotlib target/channel.\n",
  1286. "// The kernel may be null if the page has been refreshed.\n",
  1287. "if (IPython.notebook.kernel !== null) {\n",
  1288. " IPython.notebook.kernel.comm_manager.register_target(\n",
  1289. " 'matplotlib',\n",
  1290. " mpl.mpl_figure_comm\n",
  1291. " );\n",
  1292. "}\n"
  1293. ],
  1294. "text/plain": [
  1295. "<IPython.core.display.Javascript object>"
  1296. ]
  1297. },
  1298. "metadata": {},
  1299. "output_type": "display_data"
  1300. },
  1301. {
  1302. "data": {
  1303. "text/html": [

机器学习越来越多应用到飞行器、机器人等领域,其目的是利用计算机实现类似人类的智能,从而实现装备的智能化与无人化。本课程旨在引导学生掌握机器学习的基本知识、典型方法与技术,通过具体的应用案例激发学生对该学科的兴趣,鼓励学生能够从人工智能的角度来分析、解决飞行器、机器人所面临的问题和挑战。本课程主要内容包括Python编程基础,机器学习模型,无监督学习、监督学习、深度学习基础知识与实现,并学习如何利用机器学习解决实际问题,从而全面提升自我的《综合能力》。