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.

matplotlib_ani2.ipynb 78 kB

6 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844
  1. {
  2. "cells": [
  3. {
  4. "cell_type": "code",
  5. "execution_count": 1,
  6. "metadata": {},
  7. "outputs": [
  8. {
  9. "data": {
  10. "application/javascript": [
  11. "/* Put everything inside the global mpl namespace */\n",
  12. "window.mpl = {};\n",
  13. "\n",
  14. "\n",
  15. "mpl.get_websocket_type = function() {\n",
  16. " if (typeof(WebSocket) !== 'undefined') {\n",
  17. " return WebSocket;\n",
  18. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  19. " return MozWebSocket;\n",
  20. " } else {\n",
  21. " alert('Your browser does not have WebSocket support.' +\n",
  22. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  23. " 'Firefox 4 and 5 are also supported but you ' +\n",
  24. " 'have to enable WebSockets in about:config.');\n",
  25. " };\n",
  26. "}\n",
  27. "\n",
  28. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  29. " this.id = figure_id;\n",
  30. "\n",
  31. " this.ws = websocket;\n",
  32. "\n",
  33. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  34. "\n",
  35. " if (!this.supports_binary) {\n",
  36. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  37. " if (warnings) {\n",
  38. " warnings.style.display = 'block';\n",
  39. " warnings.textContent = (\n",
  40. " \"This browser does not support binary websocket messages. \" +\n",
  41. " \"Performance may be slow.\");\n",
  42. " }\n",
  43. " }\n",
  44. "\n",
  45. " this.imageObj = new Image();\n",
  46. "\n",
  47. " this.context = undefined;\n",
  48. " this.message = undefined;\n",
  49. " this.canvas = undefined;\n",
  50. " this.rubberband_canvas = undefined;\n",
  51. " this.rubberband_context = undefined;\n",
  52. " this.format_dropdown = undefined;\n",
  53. "\n",
  54. " this.image_mode = 'full';\n",
  55. "\n",
  56. " this.root = $('<div/>');\n",
  57. " this._root_extra_style(this.root)\n",
  58. " this.root.attr('style', 'display: inline-block');\n",
  59. "\n",
  60. " $(parent_element).append(this.root);\n",
  61. "\n",
  62. " this._init_header(this);\n",
  63. " this._init_canvas(this);\n",
  64. " this._init_toolbar(this);\n",
  65. "\n",
  66. " var fig = this;\n",
  67. "\n",
  68. " this.waiting = false;\n",
  69. "\n",
  70. " this.ws.onopen = function () {\n",
  71. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  72. " fig.send_message(\"send_image_mode\", {});\n",
  73. " if (mpl.ratio != 1) {\n",
  74. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  75. " }\n",
  76. " fig.send_message(\"refresh\", {});\n",
  77. " }\n",
  78. "\n",
  79. " this.imageObj.onload = function() {\n",
  80. " if (fig.image_mode == 'full') {\n",
  81. " // Full images could contain transparency (where diff images\n",
  82. " // almost always do), so we need to clear the canvas so that\n",
  83. " // there is no ghosting.\n",
  84. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  85. " }\n",
  86. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  87. " };\n",
  88. "\n",
  89. " this.imageObj.onunload = function() {\n",
  90. " fig.ws.close();\n",
  91. " }\n",
  92. "\n",
  93. " this.ws.onmessage = this._make_on_message_function(this);\n",
  94. "\n",
  95. " this.ondownload = ondownload;\n",
  96. "}\n",
  97. "\n",
  98. "mpl.figure.prototype._init_header = function() {\n",
  99. " var titlebar = $(\n",
  100. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  101. " 'ui-helper-clearfix\"/>');\n",
  102. " var titletext = $(\n",
  103. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  104. " 'text-align: center; padding: 3px;\"/>');\n",
  105. " titlebar.append(titletext)\n",
  106. " this.root.append(titlebar);\n",
  107. " this.header = titletext[0];\n",
  108. "}\n",
  109. "\n",
  110. "\n",
  111. "\n",
  112. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  113. "\n",
  114. "}\n",
  115. "\n",
  116. "\n",
  117. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  118. "\n",
  119. "}\n",
  120. "\n",
  121. "mpl.figure.prototype._init_canvas = function() {\n",
  122. " var fig = this;\n",
  123. "\n",
  124. " var canvas_div = $('<div/>');\n",
  125. "\n",
  126. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  127. "\n",
  128. " function canvas_keyboard_event(event) {\n",
  129. " return fig.key_event(event, event['data']);\n",
  130. " }\n",
  131. "\n",
  132. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  133. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  134. " this.canvas_div = canvas_div\n",
  135. " this._canvas_extra_style(canvas_div)\n",
  136. " this.root.append(canvas_div);\n",
  137. "\n",
  138. " var canvas = $('<canvas/>');\n",
  139. " canvas.addClass('mpl-canvas');\n",
  140. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  141. "\n",
  142. " this.canvas = canvas[0];\n",
  143. " this.context = canvas[0].getContext(\"2d\");\n",
  144. "\n",
  145. " var backingStore = this.context.backingStorePixelRatio ||\n",
  146. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  147. "\tthis.context.mozBackingStorePixelRatio ||\n",
  148. "\tthis.context.msBackingStorePixelRatio ||\n",
  149. "\tthis.context.oBackingStorePixelRatio ||\n",
  150. "\tthis.context.backingStorePixelRatio || 1;\n",
  151. "\n",
  152. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  153. "\n",
  154. " var rubberband = $('<canvas/>');\n",
  155. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  156. "\n",
  157. " var pass_mouse_events = true;\n",
  158. "\n",
  159. " canvas_div.resizable({\n",
  160. " start: function(event, ui) {\n",
  161. " pass_mouse_events = false;\n",
  162. " },\n",
  163. " resize: function(event, ui) {\n",
  164. " fig.request_resize(ui.size.width, ui.size.height);\n",
  165. " },\n",
  166. " stop: function(event, ui) {\n",
  167. " pass_mouse_events = true;\n",
  168. " fig.request_resize(ui.size.width, ui.size.height);\n",
  169. " },\n",
  170. " });\n",
  171. "\n",
  172. " function mouse_event_fn(event) {\n",
  173. " if (pass_mouse_events)\n",
  174. " return fig.mouse_event(event, event['data']);\n",
  175. " }\n",
  176. "\n",
  177. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  178. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  179. " // Throttle sequential mouse events to 1 every 20ms.\n",
  180. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  181. "\n",
  182. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  183. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  184. "\n",
  185. " canvas_div.on(\"wheel\", function (event) {\n",
  186. " event = event.originalEvent;\n",
  187. " event['data'] = 'scroll'\n",
  188. " if (event.deltaY < 0) {\n",
  189. " event.step = 1;\n",
  190. " } else {\n",
  191. " event.step = -1;\n",
  192. " }\n",
  193. " mouse_event_fn(event);\n",
  194. " });\n",
  195. "\n",
  196. " canvas_div.append(canvas);\n",
  197. " canvas_div.append(rubberband);\n",
  198. "\n",
  199. " this.rubberband = rubberband;\n",
  200. " this.rubberband_canvas = rubberband[0];\n",
  201. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  202. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  203. "\n",
  204. " this._resize_canvas = function(width, height) {\n",
  205. " // Keep the size of the canvas, canvas container, and rubber band\n",
  206. " // canvas in synch.\n",
  207. " canvas_div.css('width', width)\n",
  208. " canvas_div.css('height', height)\n",
  209. "\n",
  210. " canvas.attr('width', width * mpl.ratio);\n",
  211. " canvas.attr('height', height * mpl.ratio);\n",
  212. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  213. "\n",
  214. " rubberband.attr('width', width);\n",
  215. " rubberband.attr('height', height);\n",
  216. " }\n",
  217. "\n",
  218. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  219. " // upon first draw.\n",
  220. " this._resize_canvas(600, 600);\n",
  221. "\n",
  222. " // Disable right mouse context menu.\n",
  223. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  224. " return false;\n",
  225. " });\n",
  226. "\n",
  227. " function set_focus () {\n",
  228. " canvas.focus();\n",
  229. " canvas_div.focus();\n",
  230. " }\n",
  231. "\n",
  232. " window.setTimeout(set_focus, 100);\n",
  233. "}\n",
  234. "\n",
  235. "mpl.figure.prototype._init_toolbar = function() {\n",
  236. " var fig = this;\n",
  237. "\n",
  238. " var nav_element = $('<div/>')\n",
  239. " nav_element.attr('style', 'width: 100%');\n",
  240. " this.root.append(nav_element);\n",
  241. "\n",
  242. " // Define a callback function for later on.\n",
  243. " function toolbar_event(event) {\n",
  244. " return fig.toolbar_button_onclick(event['data']);\n",
  245. " }\n",
  246. " function toolbar_mouse_event(event) {\n",
  247. " return fig.toolbar_button_onmouseover(event['data']);\n",
  248. " }\n",
  249. "\n",
  250. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  251. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  252. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  253. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  254. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  255. "\n",
  256. " if (!name) {\n",
  257. " // put a spacer in here.\n",
  258. " continue;\n",
  259. " }\n",
  260. " var button = $('<button/>');\n",
  261. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  262. " 'ui-button-icon-only');\n",
  263. " button.attr('role', 'button');\n",
  264. " button.attr('aria-disabled', 'false');\n",
  265. " button.click(method_name, toolbar_event);\n",
  266. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  267. "\n",
  268. " var icon_img = $('<span/>');\n",
  269. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  270. " icon_img.addClass(image);\n",
  271. " icon_img.addClass('ui-corner-all');\n",
  272. "\n",
  273. " var tooltip_span = $('<span/>');\n",
  274. " tooltip_span.addClass('ui-button-text');\n",
  275. " tooltip_span.html(tooltip);\n",
  276. "\n",
  277. " button.append(icon_img);\n",
  278. " button.append(tooltip_span);\n",
  279. "\n",
  280. " nav_element.append(button);\n",
  281. " }\n",
  282. "\n",
  283. " var fmt_picker_span = $('<span/>');\n",
  284. "\n",
  285. " var fmt_picker = $('<select/>');\n",
  286. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  287. " fmt_picker_span.append(fmt_picker);\n",
  288. " nav_element.append(fmt_picker_span);\n",
  289. " this.format_dropdown = fmt_picker[0];\n",
  290. "\n",
  291. " for (var ind in mpl.extensions) {\n",
  292. " var fmt = mpl.extensions[ind];\n",
  293. " var option = $(\n",
  294. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  295. " fmt_picker.append(option)\n",
  296. " }\n",
  297. "\n",
  298. " // Add hover states to the ui-buttons\n",
  299. " $( \".ui-button\" ).hover(\n",
  300. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  301. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  302. " );\n",
  303. "\n",
  304. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  305. " nav_element.append(status_bar);\n",
  306. " this.message = status_bar[0];\n",
  307. "}\n",
  308. "\n",
  309. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  310. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  311. " // which will in turn request a refresh of the image.\n",
  312. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  313. "}\n",
  314. "\n",
  315. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  316. " properties['type'] = type;\n",
  317. " properties['figure_id'] = this.id;\n",
  318. " this.ws.send(JSON.stringify(properties));\n",
  319. "}\n",
  320. "\n",
  321. "mpl.figure.prototype.send_draw_message = function() {\n",
  322. " if (!this.waiting) {\n",
  323. " this.waiting = true;\n",
  324. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  325. " }\n",
  326. "}\n",
  327. "\n",
  328. "\n",
  329. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  330. " var format_dropdown = fig.format_dropdown;\n",
  331. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  332. " fig.ondownload(fig, format);\n",
  333. "}\n",
  334. "\n",
  335. "\n",
  336. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  337. " var size = msg['size'];\n",
  338. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  339. " fig._resize_canvas(size[0], size[1]);\n",
  340. " fig.send_message(\"refresh\", {});\n",
  341. " };\n",
  342. "}\n",
  343. "\n",
  344. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  345. " var x0 = msg['x0'] / mpl.ratio;\n",
  346. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  347. " var x1 = msg['x1'] / mpl.ratio;\n",
  348. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  349. " x0 = Math.floor(x0) + 0.5;\n",
  350. " y0 = Math.floor(y0) + 0.5;\n",
  351. " x1 = Math.floor(x1) + 0.5;\n",
  352. " y1 = Math.floor(y1) + 0.5;\n",
  353. " var min_x = Math.min(x0, x1);\n",
  354. " var min_y = Math.min(y0, y1);\n",
  355. " var width = Math.abs(x1 - x0);\n",
  356. " var height = Math.abs(y1 - y0);\n",
  357. "\n",
  358. " fig.rubberband_context.clearRect(\n",
  359. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  360. "\n",
  361. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  362. "}\n",
  363. "\n",
  364. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  365. " // Updates the figure title.\n",
  366. " fig.header.textContent = msg['label'];\n",
  367. "}\n",
  368. "\n",
  369. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  370. " var cursor = msg['cursor'];\n",
  371. " switch(cursor)\n",
  372. " {\n",
  373. " case 0:\n",
  374. " cursor = 'pointer';\n",
  375. " break;\n",
  376. " case 1:\n",
  377. " cursor = 'default';\n",
  378. " break;\n",
  379. " case 2:\n",
  380. " cursor = 'crosshair';\n",
  381. " break;\n",
  382. " case 3:\n",
  383. " cursor = 'move';\n",
  384. " break;\n",
  385. " }\n",
  386. " fig.rubberband_canvas.style.cursor = cursor;\n",
  387. "}\n",
  388. "\n",
  389. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  390. " fig.message.textContent = msg['message'];\n",
  391. "}\n",
  392. "\n",
  393. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  394. " // Request the server to send over a new figure.\n",
  395. " fig.send_draw_message();\n",
  396. "}\n",
  397. "\n",
  398. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  399. " fig.image_mode = msg['mode'];\n",
  400. "}\n",
  401. "\n",
  402. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  403. " // Called whenever the canvas gets updated.\n",
  404. " this.send_message(\"ack\", {});\n",
  405. "}\n",
  406. "\n",
  407. "// A function to construct a web socket function for onmessage handling.\n",
  408. "// Called in the figure constructor.\n",
  409. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  410. " return function socket_on_message(evt) {\n",
  411. " if (evt.data instanceof Blob) {\n",
  412. " /* FIXME: We get \"Resource interpreted as Image but\n",
  413. " * transferred with MIME type text/plain:\" errors on\n",
  414. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  415. " * to be part of the websocket stream */\n",
  416. " evt.data.type = \"image/png\";\n",
  417. "\n",
  418. " /* Free the memory for the previous frames */\n",
  419. " if (fig.imageObj.src) {\n",
  420. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  421. " fig.imageObj.src);\n",
  422. " }\n",
  423. "\n",
  424. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  425. " evt.data);\n",
  426. " fig.updated_canvas_event();\n",
  427. " fig.waiting = false;\n",
  428. " return;\n",
  429. " }\n",
  430. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  431. " fig.imageObj.src = evt.data;\n",
  432. " fig.updated_canvas_event();\n",
  433. " fig.waiting = false;\n",
  434. " return;\n",
  435. " }\n",
  436. "\n",
  437. " var msg = JSON.parse(evt.data);\n",
  438. " var msg_type = msg['type'];\n",
  439. "\n",
  440. " // Call the \"handle_{type}\" callback, which takes\n",
  441. " // the figure and JSON message as its only arguments.\n",
  442. " try {\n",
  443. " var callback = fig[\"handle_\" + msg_type];\n",
  444. " } catch (e) {\n",
  445. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  446. " return;\n",
  447. " }\n",
  448. "\n",
  449. " if (callback) {\n",
  450. " try {\n",
  451. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  452. " callback(fig, msg);\n",
  453. " } catch (e) {\n",
  454. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  455. " }\n",
  456. " }\n",
  457. " };\n",
  458. "}\n",
  459. "\n",
  460. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  461. "mpl.findpos = function(e) {\n",
  462. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  463. " var targ;\n",
  464. " if (!e)\n",
  465. " e = window.event;\n",
  466. " if (e.target)\n",
  467. " targ = e.target;\n",
  468. " else if (e.srcElement)\n",
  469. " targ = e.srcElement;\n",
  470. " if (targ.nodeType == 3) // defeat Safari bug\n",
  471. " targ = targ.parentNode;\n",
  472. "\n",
  473. " // jQuery normalizes the pageX and pageY\n",
  474. " // pageX,Y are the mouse positions relative to the document\n",
  475. " // offset() returns the position of the element relative to the document\n",
  476. " var x = e.pageX - $(targ).offset().left;\n",
  477. " var y = e.pageY - $(targ).offset().top;\n",
  478. "\n",
  479. " return {\"x\": x, \"y\": y};\n",
  480. "};\n",
  481. "\n",
  482. "/*\n",
  483. " * return a copy of an object with only non-object keys\n",
  484. " * we need this to avoid circular references\n",
  485. " * http://stackoverflow.com/a/24161582/3208463\n",
  486. " */\n",
  487. "function simpleKeys (original) {\n",
  488. " return Object.keys(original).reduce(function (obj, key) {\n",
  489. " if (typeof original[key] !== 'object')\n",
  490. " obj[key] = original[key]\n",
  491. " return obj;\n",
  492. " }, {});\n",
  493. "}\n",
  494. "\n",
  495. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  496. " var canvas_pos = mpl.findpos(event)\n",
  497. "\n",
  498. " if (name === 'button_press')\n",
  499. " {\n",
  500. " this.canvas.focus();\n",
  501. " this.canvas_div.focus();\n",
  502. " }\n",
  503. "\n",
  504. " var x = canvas_pos.x * mpl.ratio;\n",
  505. " var y = canvas_pos.y * mpl.ratio;\n",
  506. "\n",
  507. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  508. " step: event.step,\n",
  509. " guiEvent: simpleKeys(event)});\n",
  510. "\n",
  511. " /* This prevents the web browser from automatically changing to\n",
  512. " * the text insertion cursor when the button is pressed. We want\n",
  513. " * to control all of the cursor setting manually through the\n",
  514. " * 'cursor' event from matplotlib */\n",
  515. " event.preventDefault();\n",
  516. " return false;\n",
  517. "}\n",
  518. "\n",
  519. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  520. " // Handle any extra behaviour associated with a key event\n",
  521. "}\n",
  522. "\n",
  523. "mpl.figure.prototype.key_event = function(event, name) {\n",
  524. "\n",
  525. " // Prevent repeat events\n",
  526. " if (name == 'key_press')\n",
  527. " {\n",
  528. " if (event.which === this._key)\n",
  529. " return;\n",
  530. " else\n",
  531. " this._key = event.which;\n",
  532. " }\n",
  533. " if (name == 'key_release')\n",
  534. " this._key = null;\n",
  535. "\n",
  536. " var value = '';\n",
  537. " if (event.ctrlKey && event.which != 17)\n",
  538. " value += \"ctrl+\";\n",
  539. " if (event.altKey && event.which != 18)\n",
  540. " value += \"alt+\";\n",
  541. " if (event.shiftKey && event.which != 16)\n",
  542. " value += \"shift+\";\n",
  543. "\n",
  544. " value += 'k';\n",
  545. " value += event.which.toString();\n",
  546. "\n",
  547. " this._key_event_extra(event, name);\n",
  548. "\n",
  549. " this.send_message(name, {key: value,\n",
  550. " guiEvent: simpleKeys(event)});\n",
  551. " return false;\n",
  552. "}\n",
  553. "\n",
  554. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  555. " if (name == 'download') {\n",
  556. " this.handle_save(this, null);\n",
  557. " } else {\n",
  558. " this.send_message(\"toolbar_button\", {name: name});\n",
  559. " }\n",
  560. "};\n",
  561. "\n",
  562. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  563. " this.message.textContent = tooltip;\n",
  564. "};\n",
  565. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  566. "\n",
  567. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  568. "\n",
  569. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  570. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  571. " // object with the appropriate methods. Currently this is a non binary\n",
  572. " // socket, so there is still some room for performance tuning.\n",
  573. " var ws = {};\n",
  574. "\n",
  575. " ws.close = function() {\n",
  576. " comm.close()\n",
  577. " };\n",
  578. " ws.send = function(m) {\n",
  579. " //console.log('sending', m);\n",
  580. " comm.send(m);\n",
  581. " };\n",
  582. " // Register the callback with on_msg.\n",
  583. " comm.on_msg(function(msg) {\n",
  584. " //console.log('receiving', msg['content']['data'], msg);\n",
  585. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  586. " ws.onmessage(msg['content']['data'])\n",
  587. " });\n",
  588. " return ws;\n",
  589. "}\n",
  590. "\n",
  591. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  592. " // This is the function which gets called when the mpl process\n",
  593. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  594. "\n",
  595. " var id = msg.content.data.id;\n",
  596. " // Get hold of the div created by the display call when the Comm\n",
  597. " // socket was opened in Python.\n",
  598. " var element = $(\"#\" + id);\n",
  599. " var ws_proxy = comm_websocket_adapter(comm)\n",
  600. "\n",
  601. " function ondownload(figure, format) {\n",
  602. " window.open(figure.imageObj.src);\n",
  603. " }\n",
  604. "\n",
  605. " var fig = new mpl.figure(id, ws_proxy,\n",
  606. " ondownload,\n",
  607. " element.get(0));\n",
  608. "\n",
  609. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  610. " // web socket which is closed, not our websocket->open comm proxy.\n",
  611. " ws_proxy.onopen();\n",
  612. "\n",
  613. " fig.parent_element = element.get(0);\n",
  614. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  615. " if (!fig.cell_info) {\n",
  616. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  617. " return;\n",
  618. " }\n",
  619. "\n",
  620. " var output_index = fig.cell_info[2]\n",
  621. " var cell = fig.cell_info[0];\n",
  622. "\n",
  623. "};\n",
  624. "\n",
  625. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  626. " var width = fig.canvas.width/mpl.ratio\n",
  627. " fig.root.unbind('remove')\n",
  628. "\n",
  629. " // Update the output cell to use the data from the current canvas.\n",
  630. " fig.push_to_output();\n",
  631. " var dataURL = fig.canvas.toDataURL();\n",
  632. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  633. " // the notebook keyboard shortcuts fail.\n",
  634. " IPython.keyboard_manager.enable()\n",
  635. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  636. " fig.close_ws(fig, msg);\n",
  637. "}\n",
  638. "\n",
  639. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  640. " fig.send_message('closing', msg);\n",
  641. " // fig.ws.close()\n",
  642. "}\n",
  643. "\n",
  644. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  645. " // Turn the data on the canvas into data in the output cell.\n",
  646. " var width = this.canvas.width/mpl.ratio\n",
  647. " var dataURL = this.canvas.toDataURL();\n",
  648. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  649. "}\n",
  650. "\n",
  651. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  652. " // Tell IPython that the notebook contents must change.\n",
  653. " IPython.notebook.set_dirty(true);\n",
  654. " this.send_message(\"ack\", {});\n",
  655. " var fig = this;\n",
  656. " // Wait a second, then push the new image to the DOM so\n",
  657. " // that it is saved nicely (might be nice to debounce this).\n",
  658. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  659. "}\n",
  660. "\n",
  661. "mpl.figure.prototype._init_toolbar = function() {\n",
  662. " var fig = this;\n",
  663. "\n",
  664. " var nav_element = $('<div/>')\n",
  665. " nav_element.attr('style', 'width: 100%');\n",
  666. " this.root.append(nav_element);\n",
  667. "\n",
  668. " // Define a callback function for later on.\n",
  669. " function toolbar_event(event) {\n",
  670. " return fig.toolbar_button_onclick(event['data']);\n",
  671. " }\n",
  672. " function toolbar_mouse_event(event) {\n",
  673. " return fig.toolbar_button_onmouseover(event['data']);\n",
  674. " }\n",
  675. "\n",
  676. " for(var toolbar_ind in mpl.toolbar_items){\n",
  677. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  678. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  679. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  680. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  681. "\n",
  682. " if (!name) { continue; };\n",
  683. "\n",
  684. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  685. " button.click(method_name, toolbar_event);\n",
  686. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  687. " nav_element.append(button);\n",
  688. " }\n",
  689. "\n",
  690. " // Add the status bar.\n",
  691. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  692. " nav_element.append(status_bar);\n",
  693. " this.message = status_bar[0];\n",
  694. "\n",
  695. " // Add the close button to the window.\n",
  696. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  697. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  698. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  699. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  700. " buttongrp.append(button);\n",
  701. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  702. " titlebar.prepend(buttongrp);\n",
  703. "}\n",
  704. "\n",
  705. "mpl.figure.prototype._root_extra_style = function(el){\n",
  706. " var fig = this\n",
  707. " el.on(\"remove\", function(){\n",
  708. "\tfig.close_ws(fig, {});\n",
  709. " });\n",
  710. "}\n",
  711. "\n",
  712. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  713. " // this is important to make the div 'focusable\n",
  714. " el.attr('tabindex', 0)\n",
  715. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  716. " // off when our div gets focus\n",
  717. "\n",
  718. " // location in version 3\n",
  719. " if (IPython.notebook.keyboard_manager) {\n",
  720. " IPython.notebook.keyboard_manager.register_events(el);\n",
  721. " }\n",
  722. " else {\n",
  723. " // location in version 2\n",
  724. " IPython.keyboard_manager.register_events(el);\n",
  725. " }\n",
  726. "\n",
  727. "}\n",
  728. "\n",
  729. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  730. " var manager = IPython.notebook.keyboard_manager;\n",
  731. " if (!manager)\n",
  732. " manager = IPython.keyboard_manager;\n",
  733. "\n",
  734. " // Check for shift+enter\n",
  735. " if (event.shiftKey && event.which == 13) {\n",
  736. " this.canvas_div.blur();\n",
  737. " event.shiftKey = false;\n",
  738. " // Send a \"J\" for go to next cell\n",
  739. " event.which = 74;\n",
  740. " event.keyCode = 74;\n",
  741. " manager.command_mode();\n",
  742. " manager.handle_keydown(event);\n",
  743. " }\n",
  744. "}\n",
  745. "\n",
  746. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  747. " fig.ondownload(fig, null);\n",
  748. "}\n",
  749. "\n",
  750. "\n",
  751. "mpl.find_output_cell = function(html_output) {\n",
  752. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  753. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  754. " // IPython event is triggered only after the cells have been serialised, which for\n",
  755. " // our purposes (turning an active figure into a static one), is too late.\n",
  756. " var cells = IPython.notebook.get_cells();\n",
  757. " var ncells = cells.length;\n",
  758. " for (var i=0; i<ncells; i++) {\n",
  759. " var cell = cells[i];\n",
  760. " if (cell.cell_type === 'code'){\n",
  761. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  762. " var data = cell.output_area.outputs[j];\n",
  763. " if (data.data) {\n",
  764. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  765. " data = data.data;\n",
  766. " }\n",
  767. " if (data['text/html'] == html_output) {\n",
  768. " return [cell, data, j];\n",
  769. " }\n",
  770. " }\n",
  771. " }\n",
  772. " }\n",
  773. "}\n",
  774. "\n",
  775. "// Register the function which deals with the matplotlib target/channel.\n",
  776. "// The kernel may be null if the page has been refreshed.\n",
  777. "if (IPython.notebook.kernel != null) {\n",
  778. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  779. "}\n"
  780. ],
  781. "text/plain": [
  782. "<IPython.core.display.Javascript object>"
  783. ]
  784. },
  785. "metadata": {},
  786. "output_type": "display_data"
  787. },
  788. {
  789. "data": {
  790. "text/html": [
  791. "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4XuydB9yN5f/HP7YkSRlZGaWSUDKTRFmpSEkqo6lCIVKZka3MQrJ+sgvJSDIqREY2ZW8NkVH2//U5l+P/4Hk85zzXGfd97s/39fJquK/1vj/nXN9zje832blz585BJgIiIAIiIAIiIAIi4BkCyeQAeuZda6AiIAIiIAIiIAIi4CMgB1BCEAEREAEREAEREAGPEZAD6LEXruGKgAiIgAiIgAiIgBxAaUAEREAEREAEREAEPEZADqDHXriGKwIiIAIiIAIiIAJyAKUBERABERABERABEfAYATmAHnvhGq4IiIAIiIAIiIAIyAGUBkRABERABERABETAYwTkAHrshWu4IiACIiACIiACIiAHUBoQAREQAREQAREQAY8RkAPosReu4YqACIiACIiACIiAHEBpQAREQAREQAREQAQ8RkAOoMdeuIYrAiIgAiIgAiIgAnIApQEREAEREAEREAER8BgBOYAee+EargiIgAiIgAiIgAjIAZQGREAEREAEREAERMBjBOQAeuyFa7giIAIiIAIiIAIiIAdQGhABERABERABERABjxGQA+ixF67hioAIiIAIiIAIiIAcQGlABERABERABERABDxGQA6gx164hisCIiACIiACIiACcgClAREQAREQAREQARHwGAE5gB574RquCIiACIiACIiACMgBlAZEQAREQAREQAREwGME5AB67IVruCIgAiIgAiIgAiIgB1AaEAEREAEREAEREAGPEZAD6LEXruGKgAiIgAiIgAiIgBxAaUAEREAEREAEREAEPEZADqDHXriGKwIiIAIiIAIiIAJyAKUBERABERABERABEfAYATmAHnvhGq4IiIAIiIAIiIAIyAGUBkRABERABERABETAYwTkAHrshWu4IiACIiACIiACIiAHUBoQAREQAREQAREQAY8RkAPosReu4YqACIiACIiACIiAHEBpQAREQAREQAREQAQ8RkAOoMdeuIYrAiIgAiIgAiIgAnIApQEREAEREAEREAER8BgBOYAee+EargiIgAiIgAiIgAjIAZQGREAEREAEREAERMBjBOQAeuyFa7giIAIiIAIiIAIiIAdQGhABERABERABERABjxGQA+ixF67hioAIiIAIiIAIiIAcQGlABERABERABERABDxGQA6gx164hisCIiACIiACIiACcgClAREQAREQAREQARHwGAE5gB574RquCIiACIiACIiACMgBlAZEQAREQAREQAREwGME5AB67IVruCIgAiIgAiIgAiIgB1AaEAEREAEREAEREAGPEZAD6LEXruGKgAiIgAiIgAiIgBxAaUAEREAEREAEREAEPEZADqDHXriGKwIiIAIiIAIiIAJyAKUBERABERABERABEfAYATmAHnvhGq4IiIAIiIAIiIAIyAGUBkRABERABERABETAYwTkAFq88LNnz2Lv3r245pprkCxZMouaVFQEREAEREAERCBSBM6dO4cjR44ge/bsSJ48eaSadVQ7cgAtXsfu3buRK1cuixpUVAREQAREQAREIFoEdu3ahZw5c0ar+ai2KwfQAv/hw4eRMWNGUEAZMmSwqElFRUAEREAEREAEIkXgn3/+8S3gHDp0CNdee22kmnVUO3IALV4HBUTh0BGUA2gBUkVFQAREQAREIIIENH8DcgAtBCcBWcBTUREQAREQARGIEgHN33IAraQnAVnhU2EREAEREAERiAoBzd9yAK2EJwFZ4VNhERABERABEYgKAc3fcgCthCcBWeFTYREQAREQARGICgHN33IArYQnAVnhU2EREAEREAERiAoBzd9yAK2EJwFZ4VNhERABERABEYgKAc3fcgCthCcBWeFTYREQAREQARGICgHN33IArYQnAVnhU2EREAEREAERiAoBzd9yAK2EJwFZ4VNhERABERABEYgKAc3fLnEAv//+e/Ts2RPLly/Hvn37MHnyZNSoUeOKopk/fz6aN2+OdevW+dK9tGnTBg0aNLiozMCBA3317t+/H0WKFEH//v1RokSJgMUoAQWMSg+KgAiIgAiIgGMIaP52iQM4c+ZMLFy4EMWKFcPjjz+eqAO4bds2FCpUCI0aNcKLL76I7777Dm+++SamT5+OypUr+wQ4fvx41KtXD4MGDULJkiXRp08fTJw4EZs2bUKWLFkCEqkEFBAmPSQCIiACIiACjiKg+dslDmBc1SRLlixRB/Dtt9/2OXtr1669ULROnTq+pM+zZs3y/T86fcWLF8eAAQN8/3327FnfSmGTJk3QunXrgIQqAQWESQ+JgAiIgAiIgKMIaP6OUQewXLlyuPvuu32ren4bPny4bxXw8OHDOHnyJNKlS4dJkyZd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asnJBLjjwNXwUaOA555zck9d2zfN33IArcQrAVnhc37hSZPMAWzl/g3/u/LnBr77bmD58vC3pxZEwKkENm4Ebr8dSJXKBH9W7t+wvCnN33IArYQlAVnhc35hZqlgtgrFqAv/u+I5p2zZgLNnga1bTfwzmQh4kcAHHwBt2gBVqgAzZ3qRQBCH+iIAACAASURBVETGrPlbDqCV0CQgK3zOLnzihAlPcuQIwHRMpUo5u7+x0LsHHgDmzwd69QJatIiFEWkMIhA8Aa6Cr1wJfPop8OKLwZdXiYAIaP52mQM4cOBA9OzZE/v370eRIkXQv39/lEggfdSIESPQsGHDi4SQJk0a/Md4Y+ft3LlzaN++PT799FMcOnQI9957Lz755BPccsstElBABGL4oenTgerVTQaQXbuA5MljeLAOGdqAAUCTJkDp0sCiRQ7plLohAhEkwNVvHjnh983+/eZHqCwsBOQAusgBHD9+POrVq4dBgwahZMmS6NOnDyZOnIhNmzYhC28QXmJ0AN944w3f3/stWbJkyJo164X/7t69O7p27YqRI0cib968aNu2LdasWYP169cjbdq0iYpOAkoUkXsfeOEFYNgwoHFjoH9/947DTT3fswfImdP0ePduIEcON/VefRUBewJc/eaRE66Gz51rX59qSJCA5m8XOYB0+ooXL44BXCUAjwqdRa5cudCkSRO0jic7Ax3AN99807eyF59x9S979uxo0aIF3nrrLd8jhw8f9jmILFuHOUoTMQkoMUIu/XsGfeZ5tL/+Ml/C/DKWRYZAmTJmy52f89dfj0ybakUEnEKAq98//ST9R+B9aP52iQN48uRJpEuXDpMmTUKNOAmx69ev73Pwpk6deplc6MS9+OKLyJEjh89ZvPvuu9GlSxfccccdvme3bt2K/PnzY+XKlShatOiF8vfff7/vv/v27XtZnSdOnAD/+I0CohNKxzFDhgwRkKyaiAiBefOAChWA66832zApU0akWTUCoHdvgD/ItAIiOXiNwL595sgJjavh/n/3GocIjVcOoEscwL179/ocuUWLFqE0fyGdt1atWmHBggVYsmTJZZJZvHgxfvvtNxQuXNjnoPXq1Qvff/891q1bh5w5c/rq4pk/1n3jjTdeKF+7dm1wq5hbzpdahw4d0DGeYMByACP0iY1UMzyHxhWo558HPvssUq2qHRLYtg3I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\" width=\"640\">"
  792. ],
  793. "text/plain": [
  794. "<IPython.core.display.HTML object>"
  795. ]
  796. },
  797. "metadata": {},
  798. "output_type": "display_data"
  799. }
  800. ],
  801. "source": [
  802. "%matplotlib nbagg\n",
  803. "\n",
  804. "import numpy as np\n",
  805. "import matplotlib.pyplot as plt\n",
  806. "import matplotlib.animation as animation\n",
  807. "\n",
  808. "fig = plt.figure()\n",
  809. "x = np.arange(0, 10, 0.1)\n",
  810. "\n",
  811. "ims = []\n",
  812. "for a in range(50):\n",
  813. " y = np.sin(x - a)\n",
  814. " im = plt.plot(x, y, \"r\")\n",
  815. " ims.append(im)\n",
  816. "\n",
  817. "ani = animation.ArtistAnimation(fig, ims)\n",
  818. "plt.show()"
  819. ]
  820. }
  821. ],
  822. "metadata": {
  823. "kernelspec": {
  824. "display_name": "Python 3",
  825. "language": "python",
  826. "name": "python3"
  827. },
  828. "language_info": {
  829. "codemirror_mode": {
  830. "name": "ipython",
  831. "version": 3
  832. },
  833. "file_extension": ".py",
  834. "mimetype": "text/x-python",
  835. "name": "python",
  836. "nbconvert_exporter": "python",
  837. "pygments_lexer": "ipython3",
  838. "version": "3.5.2"
  839. },
  840. "main_language": "python"
  841. },
  842. "nbformat": 4,
  843. "nbformat_minor": 2
  844. }

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

Contributors (1)