Skip to content

Instantly share code, notes, and snippets.

@justinsalamon
Last active April 14, 2016 16:43
Show Gist options
  • Save justinsalamon/b2a837a889a61a69b76a42a4ff38d889 to your computer and use it in GitHub Desktop.
Save justinsalamon/b2a837a889a61a69b76a42a4ff38d889 to your computer and use it in GitHub Desktop.
Compare Average Overlap Ratio metric as computed by MIREX (Duan implementation) and mir_eval
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from justin.jupyter import *\n",
"import mir_eval as me\n",
"%matplotlib inline"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"bwfile = '/Users/justin/datasets/transcription/MIREX_2015_Su_dataset/results_mirex_2015/BW2/BW2.results.csv'\n",
"bw = pd.read_csv(bwfile)\n",
"bw = bw.fillna(0)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Filename</th>\n",
" <th>Nref</th>\n",
" <th>Nsys</th>\n",
" <th>Ncorr</th>\n",
" <th>Precision</th>\n",
" <th>Recall</th>\n",
" <th>Ave. F-measure</th>\n",
" <th>Ave. Overlap</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>PQ02_Elgar_tutti.mid</td>\n",
" <td>235</td>\n",
" <td>208</td>\n",
" <td>13</td>\n",
" <td>0.062500</td>\n",
" <td>0.055319</td>\n",
" <td>0.058691</td>\n",
" <td>0.894910</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>PQ03_Farranc_tutti.mid</td>\n",
" <td>296</td>\n",
" <td>139</td>\n",
" <td>24</td>\n",
" <td>0.172662</td>\n",
" <td>0.081081</td>\n",
" <td>0.110345</td>\n",
" <td>0.813484</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>PS01_Beethoven_tutti.mid</td>\n",
" <td>138</td>\n",
" <td>189</td>\n",
" <td>22</td>\n",
" <td>0.116402</td>\n",
" <td>0.159420</td>\n",
" <td>0.134557</td>\n",
" <td>0.872352</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>PS02_Chopin_tutti.mid</td>\n",
" <td>117</td>\n",
" <td>109</td>\n",
" <td>10</td>\n",
" <td>0.091743</td>\n",
" <td>0.085470</td>\n",
" <td>0.088496</td>\n",
" <td>0.835378</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>PS03_Mozart_tutti.mid</td>\n",
" <td>193</td>\n",
" <td>181</td>\n",
" <td>14</td>\n",
" <td>0.077348</td>\n",
" <td>0.072539</td>\n",
" <td>0.074866</td>\n",
" <td>0.833365</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>SQ01_Beethoven_tutti.mid</td>\n",
" <td>96</td>\n",
" <td>210</td>\n",
" <td>0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>SQ02_Janacek_tutti.mid</td>\n",
" <td>154</td>\n",
" <td>140</td>\n",
" <td>14</td>\n",
" <td>0.100000</td>\n",
" <td>0.090909</td>\n",
" <td>0.095238</td>\n",
" <td>0.827979</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>SQ03_Schubert_tutti.mid</td>\n",
" <td>318</td>\n",
" <td>189</td>\n",
" <td>15</td>\n",
" <td>0.079365</td>\n",
" <td>0.047170</td>\n",
" <td>0.059172</td>\n",
" <td>0.875377</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>VS01_Schumann_tutti.mid</td>\n",
" <td>401</td>\n",
" <td>192</td>\n",
" <td>17</td>\n",
" <td>0.088542</td>\n",
" <td>0.042394</td>\n",
" <td>0.057336</td>\n",
" <td>0.834484</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>VS04_Franck_tutti.mid</td>\n",
" <td>311</td>\n",
" <td>235</td>\n",
" <td>20</td>\n",
" <td>0.085106</td>\n",
" <td>0.064309</td>\n",
" <td>0.073260</td>\n",
" <td>0.857476</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>Ave.</td>\n",
" <td>0.087367</td>\n",
" <td>0.069861</td>\n",
" <td>0.075196</td>\n",
" <td>0.764481</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Filename Nref Nsys Ncorr Precision Recall \\\n",
"0 PQ02_Elgar_tutti.mid 235 208 13 0.062500 0.055319 \n",
"1 PQ03_Farranc_tutti.mid 296 139 24 0.172662 0.081081 \n",
"2 PS01_Beethoven_tutti.mid 138 189 22 0.116402 0.159420 \n",
"3 PS02_Chopin_tutti.mid 117 109 10 0.091743 0.085470 \n",
"4 PS03_Mozart_tutti.mid 193 181 14 0.077348 0.072539 \n",
"5 SQ01_Beethoven_tutti.mid 96 210 0 0.000000 0.000000 \n",
"6 SQ02_Janacek_tutti.mid 154 140 14 0.100000 0.090909 \n",
"7 SQ03_Schubert_tutti.mid 318 189 15 0.079365 0.047170 \n",
"8 VS01_Schumann_tutti.mid 401 192 17 0.088542 0.042394 \n",
"9 VS04_Franck_tutti.mid 311 235 20 0.085106 0.064309 \n",
"10 0 0 0 Ave. 0.087367 0.069861 \n",
"\n",
" Ave. F-measure Ave. Overlap \n",
"0 0.058691 0.894910 \n",
"1 0.110345 0.813484 \n",
"2 0.134557 0.872352 \n",
"3 0.088496 0.835378 \n",
"4 0.074866 0.833365 \n",
"5 0.000000 0.000000 \n",
"6 0.095238 0.827979 \n",
"7 0.059172 0.875377 \n",
"8 0.057336 0.834484 \n",
"9 0.073260 0.857476 \n",
"10 0.075196 0.764481 "
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"bw"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"estfolder = '/Users/justin/datasets/transcription/MIREX_2015_Su_dataset/alg_output_mirex_2015/algo_note/BW2/'\n",
"reffolder = '/Users/justin/datasets/transcription/MIREX_2015_Su_dataset/gt_textfrommidi/'\n",
"estfiles = glob.glob(os.path.join(estfolder, \"*.txt\"))\n",
"reffiles = glob.glob(os.path.join(reffolder, \"*.txt\"))"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"allscores = []\n",
"names = []\n",
"\n",
"for reffile, estfile in zip(reffiles, estfiles):\n",
" \n",
" assert (os.path.basename(reffile).split(\"_\"))[0] == (os.path.basename(estfile).split(\"_\"))[0]\n",
" \n",
" ref_int, ref_pitch = me.io.load_valued_intervals(reffile, delimiter=',')\n",
" est_int, est_pitch = me.io.load_valued_intervals(estfile)\n",
" scores = me.transcription.evaluate(ref_int, ref_pitch, est_int, est_pitch)\n",
" allscores.append(scores)\n",
" names.append((os.path.basename(reffile).split(\"_\"))[0])"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"bw_aors = bw['Ave. Overlap'][:10]\n",
"bw_aors_mireval = [s['Average_Overlap_Ratio'] for s in allscores]"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\n",
"\n",
"mpl.get_websocket_type = function() {\n",
" if (typeof(WebSocket) !== 'undefined') {\n",
" return WebSocket;\n",
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
" return MozWebSocket;\n",
" } else {\n",
" alert('Your browser does not have WebSocket support.' +\n",
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
" 'Firefox 4 and 5 are also supported but you ' +\n",
" 'have to enable WebSockets in about:config.');\n",
" };\n",
"}\n",
"\n",
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
" this.id = figure_id;\n",
"\n",
" this.ws = websocket;\n",
"\n",
" this.supports_binary = (this.ws.binaryType != undefined);\n",
"\n",
" if (!this.supports_binary) {\n",
" var warnings = document.getElementById(\"mpl-warnings\");\n",
" if (warnings) {\n",
" warnings.style.display = 'block';\n",
" warnings.textContent = (\n",
" \"This browser does not support binary websocket messages. \" +\n",
" \"Performance may be slow.\");\n",
" }\n",
" }\n",
"\n",
" this.imageObj = new Image();\n",
"\n",
" this.context = undefined;\n",
" this.message = undefined;\n",
" this.canvas = undefined;\n",
" this.rubberband_canvas = undefined;\n",
" this.rubberband_context = undefined;\n",
" this.format_dropdown = undefined;\n",
"\n",
" this.image_mode = 'full';\n",
"\n",
" this.root = $('<div/>');\n",
" this._root_extra_style(this.root)\n",
" this.root.attr('style', 'display: inline-block');\n",
"\n",
" $(parent_element).append(this.root);\n",
"\n",
" this._init_header(this);\n",
" this._init_canvas(this);\n",
" this._init_toolbar(this);\n",
"\n",
" var fig = this;\n",
"\n",
" this.waiting = false;\n",
"\n",
" this.ws.onopen = function () {\n",
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
" fig.send_message(\"send_image_mode\", {});\n",
" fig.send_message(\"refresh\", {});\n",
" }\n",
"\n",
" this.imageObj.onload = function() {\n",
" if (fig.image_mode == 'full') {\n",
" // Full images could contain transparency (where diff images\n",
" // almost always do), so we need to clear the canvas so that\n",
" // there is no ghosting.\n",
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
" }\n",
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
" fig.waiting = false;\n",
" };\n",
"\n",
" this.imageObj.onunload = function() {\n",
" this.ws.close();\n",
" }\n",
"\n",
" this.ws.onmessage = this._make_on_message_function(this);\n",
"\n",
" this.ondownload = ondownload;\n",
"}\n",
"\n",
"mpl.figure.prototype._init_header = function() {\n",
" var titlebar = $(\n",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\n",
" titlebar.append(titletext)\n",
" this.root.append(titlebar);\n",
" this.header = titletext[0];\n",
"}\n",
"\n",
"\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._init_canvas = function() {\n",
" var fig = this;\n",
"\n",
" var canvas_div = $('<div/>');\n",
"\n",
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
"\n",
" function canvas_keyboard_event(event) {\n",
" return fig.key_event(event, event['data']);\n",
" }\n",
"\n",
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
" this.canvas_div = canvas_div\n",
" this._canvas_extra_style(canvas_div)\n",
" this.root.append(canvas_div);\n",
"\n",
" var canvas = $('<canvas/>');\n",
" canvas.addClass('mpl-canvas');\n",
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
"\n",
" this.canvas = canvas[0];\n",
" this.context = canvas[0].getContext(\"2d\");\n",
"\n",
" var rubberband = $('<canvas/>');\n",
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
"\n",
" var pass_mouse_events = true;\n",
"\n",
" canvas_div.resizable({\n",
" start: function(event, ui) {\n",
" pass_mouse_events = false;\n",
" },\n",
" resize: function(event, ui) {\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" stop: function(event, ui) {\n",
" pass_mouse_events = true;\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" });\n",
"\n",
" function mouse_event_fn(event) {\n",
" if (pass_mouse_events)\n",
" return fig.mouse_event(event, event['data']);\n",
" }\n",
"\n",
" rubberband.mousedown('button_press', mouse_event_fn);\n",
" rubberband.mouseup('button_release', mouse_event_fn);\n",
" // Throttle sequential mouse events to 1 every 20ms.\n",
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
"\n",
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
"\n",
" canvas_div.on(\"wheel\", function (event) {\n",
" event = event.originalEvent;\n",
" event['data'] = 'scroll'\n",
" if (event.deltaY < 0) {\n",
" event.step = 1;\n",
" } else {\n",
" event.step = -1;\n",
" }\n",
" mouse_event_fn(event);\n",
" });\n",
"\n",
" canvas_div.append(canvas);\n",
" canvas_div.append(rubberband);\n",
"\n",
" this.rubberband = rubberband;\n",
" this.rubberband_canvas = rubberband[0];\n",
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
" this.rubberband_context.strokeStyle = \"#000000\";\n",
"\n",
" this._resize_canvas = function(width, height) {\n",
" // Keep the size of the canvas, canvas container, and rubber band\n",
" // canvas in synch.\n",
" canvas_div.css('width', width)\n",
" canvas_div.css('height', height)\n",
"\n",
" canvas.attr('width', width);\n",
" canvas.attr('height', height);\n",
"\n",
" rubberband.attr('width', width);\n",
" rubberband.attr('height', height);\n",
" }\n",
"\n",
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
" // upon first draw.\n",
" this._resize_canvas(600, 600);\n",
"\n",
" // Disable right mouse context menu.\n",
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
" return false;\n",
" });\n",
"\n",
" function set_focus () {\n",
" canvas.focus();\n",
" canvas_div.focus();\n",
" }\n",
"\n",
" window.setTimeout(set_focus, 100);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('<div/>')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items) {\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) {\n",
" // put a spacer in here.\n",
" continue;\n",
" }\n",
" var button = $('<button/>');\n",
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
" 'ui-button-icon-only');\n",
" button.attr('role', 'button');\n",
" button.attr('aria-disabled', 'false');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
"\n",
" var icon_img = $('<span/>');\n",
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
" icon_img.addClass(image);\n",
" icon_img.addClass('ui-corner-all');\n",
"\n",
" var tooltip_span = $('<span/>');\n",
" tooltip_span.addClass('ui-button-text');\n",
" tooltip_span.html(tooltip);\n",
"\n",
" button.append(icon_img);\n",
" button.append(tooltip_span);\n",
"\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" var fmt_picker_span = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\n",
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
" fmt_picker_span.append(fmt_picker);\n",
" nav_element.append(fmt_picker_span);\n",
" this.format_dropdown = fmt_picker[0];\n",
"\n",
" for (var ind in mpl.extensions) {\n",
" var fmt = mpl.extensions[ind];\n",
" var option = $(\n",
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
" fmt_picker.append(option)\n",
" }\n",
"\n",
" // Add hover states to the ui-buttons\n",
" $( \".ui-button\" ).hover(\n",
" function() { $(this).addClass(\"ui-state-hover\");},\n",
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
" );\n",
"\n",
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"}\n",
"\n",
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
" // which will in turn request a refresh of the image.\n",
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
"}\n",
"\n",
"mpl.figure.prototype.send_message = function(type, properties) {\n",
" properties['type'] = type;\n",
" properties['figure_id'] = this.id;\n",
" this.ws.send(JSON.stringify(properties));\n",
"}\n",
"\n",
"mpl.figure.prototype.send_draw_message = function() {\n",
" if (!this.waiting) {\n",
" this.waiting = true;\n",
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
" }\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" var format_dropdown = fig.format_dropdown;\n",
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
" fig.ondownload(fig, format);\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
" var size = msg['size'];\n",
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
" fig._resize_canvas(size[0], size[1]);\n",
" fig.send_message(\"refresh\", {});\n",
" };\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
" var x0 = msg['x0'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\n",
" x0 = Math.floor(x0) + 0.5;\n",
" y0 = Math.floor(y0) + 0.5;\n",
" x1 = Math.floor(x1) + 0.5;\n",
" y1 = Math.floor(y1) + 0.5;\n",
" var min_x = Math.min(x0, x1);\n",
" var min_y = Math.min(y0, y1);\n",
" var width = Math.abs(x1 - x0);\n",
" var height = Math.abs(y1 - y0);\n",
"\n",
" fig.rubberband_context.clearRect(\n",
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
"\n",
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
" // Updates the figure title.\n",
" fig.header.textContent = msg['label'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
" var cursor = msg['cursor'];\n",
" switch(cursor)\n",
" {\n",
" case 0:\n",
" cursor = 'pointer';\n",
" break;\n",
" case 1:\n",
" cursor = 'default';\n",
" break;\n",
" case 2:\n",
" cursor = 'crosshair';\n",
" break;\n",
" case 3:\n",
" cursor = 'move';\n",
" break;\n",
" }\n",
" fig.rubberband_canvas.style.cursor = cursor;\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
" fig.message.textContent = msg['message'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
" // Request the server to send over a new figure.\n",
" fig.send_draw_message();\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
" fig.image_mode = msg['mode'];\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Called whenever the canvas gets updated.\n",
" this.send_message(\"ack\", {});\n",
"}\n",
"\n",
"// A function to construct a web socket function for onmessage handling.\n",
"// Called in the figure constructor.\n",
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
" return function socket_on_message(evt) {\n",
" if (evt.data instanceof Blob) {\n",
" /* FIXME: We get \"Resource interpreted as Image but\n",
" * transferred with MIME type text/plain:\" errors on\n",
" * Chrome. But how to set the MIME type? It doesn't seem\n",
" * to be part of the websocket stream */\n",
" evt.data.type = \"image/png\";\n",
"\n",
" /* Free the memory for the previous frames */\n",
" if (fig.imageObj.src) {\n",
" (window.URL || window.webkitURL).revokeObjectURL(\n",
" fig.imageObj.src);\n",
" }\n",
"\n",
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
" evt.data);\n",
" fig.updated_canvas_event();\n",
" return;\n",
" }\n",
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
" fig.imageObj.src = evt.data;\n",
" fig.updated_canvas_event();\n",
" return;\n",
" }\n",
"\n",
" var msg = JSON.parse(evt.data);\n",
" var msg_type = msg['type'];\n",
"\n",
" // Call the \"handle_{type}\" callback, which takes\n",
" // the figure and JSON message as its only arguments.\n",
" try {\n",
" var callback = fig[\"handle_\" + msg_type];\n",
" } catch (e) {\n",
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
" return;\n",
" }\n",
"\n",
" if (callback) {\n",
" try {\n",
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
" callback(fig, msg);\n",
" } catch (e) {\n",
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
" }\n",
" }\n",
" };\n",
"}\n",
"\n",
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
"mpl.findpos = function(e) {\n",
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
" var targ;\n",
" if (!e)\n",
" e = window.event;\n",
" if (e.target)\n",
" targ = e.target;\n",
" else if (e.srcElement)\n",
" targ = e.srcElement;\n",
" if (targ.nodeType == 3) // defeat Safari bug\n",
" targ = targ.parentNode;\n",
"\n",
" // jQuery normalizes the pageX and pageY\n",
" // pageX,Y are the mouse positions relative to the document\n",
" // offset() returns the position of the element relative to the document\n",
" var x = e.pageX - $(targ).offset().left;\n",
" var y = e.pageY - $(targ).offset().top;\n",
"\n",
" return {\"x\": x, \"y\": y};\n",
"};\n",
"\n",
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
" var canvas_pos = mpl.findpos(event)\n",
"\n",
" if (name === 'button_press')\n",
" {\n",
" this.canvas.focus();\n",
" this.canvas_div.focus();\n",
" }\n",
"\n",
" var x = canvas_pos.x;\n",
" var y = canvas_pos.y;\n",
"\n",
" this.send_message(name, {x: x, y: y, button: event.button,\n",
" step: event.step});\n",
"\n",
" /* This prevents the web browser from automatically changing to\n",
" * the text insertion cursor when the button is pressed. We want\n",
" * to control all of the cursor setting manually through the\n",
" * 'cursor' event from matplotlib */\n",
" event.preventDefault();\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" // Handle any extra behaviour associated with a key event\n",
"}\n",
"\n",
"mpl.figure.prototype.key_event = function(event, name) {\n",
"\n",
" // Prevent repeat events\n",
" if (name == 'key_press')\n",
" {\n",
" if (event.which === this._key)\n",
" return;\n",
" else\n",
" this._key = event.which;\n",
" }\n",
" if (name == 'key_release')\n",
" this._key = null;\n",
"\n",
" var value = '';\n",
" if (event.ctrlKey && event.which != 17)\n",
" value += \"ctrl+\";\n",
" if (event.altKey && event.which != 18)\n",
" value += \"alt+\";\n",
" if (event.shiftKey && event.which != 16)\n",
" value += \"shift+\";\n",
"\n",
" value += 'k';\n",
" value += event.which.toString();\n",
"\n",
" this._key_event_extra(event, name);\n",
"\n",
" this.send_message(name, {key: value});\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
" if (name == 'download') {\n",
" this.handle_save(this, null);\n",
" } else {\n",
" this.send_message(\"toolbar_button\", {name: name});\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
" this.message.textContent = tooltip;\n",
"};\n",
"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",
"\n",
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
"\n",
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
" // object with the appropriate methods. Currently this is a non binary\n",
" // socket, so there is still some room for performance tuning.\n",
" var ws = {};\n",
"\n",
" ws.close = function() {\n",
" comm.close()\n",
" };\n",
" ws.send = function(m) {\n",
" //console.log('sending', m);\n",
" comm.send(m);\n",
" };\n",
" // Register the callback with on_msg.\n",
" comm.on_msg(function(msg) {\n",
" //console.log('receiving', msg['content']['data'], msg);\n",
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
" ws.onmessage(msg['content']['data'])\n",
" });\n",
" return ws;\n",
"}\n",
"\n",
"mpl.mpl_figure_comm = function(comm, msg) {\n",
" // This is the function which gets called when the mpl process\n",
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
"\n",
" var id = msg.content.data.id;\n",
" // Get hold of the div created by the display call when the Comm\n",
" // socket was opened in Python.\n",
" var element = $(\"#\" + id);\n",
" var ws_proxy = comm_websocket_adapter(comm)\n",
"\n",
" function ondownload(figure, format) {\n",
" window.open(figure.imageObj.src);\n",
" }\n",
"\n",
" var fig = new mpl.figure(id, ws_proxy,\n",
" ondownload,\n",
" element.get(0));\n",
"\n",
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
" // web socket which is closed, not our websocket->open comm proxy.\n",
" ws_proxy.onopen();\n",
"\n",
" fig.parent_element = element.get(0);\n",
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
" if (!fig.cell_info) {\n",
" console.error(\"Failed to find cell for figure\", id, fig);\n",
" return;\n",
" }\n",
"\n",
" var output_index = fig.cell_info[2]\n",
" var cell = fig.cell_info[0];\n",
"\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
" // Update the output cell to use the data from the current canvas.\n",
" fig.push_to_output();\n",
" var dataURL = fig.canvas.toDataURL();\n",
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
" // the notebook keyboard shortcuts fail.\n",
" IPython.keyboard_manager.enable()\n",
" $(fig.parent_element).html('<img src=\"' + dataURL + '\">');\n",
" fig.send_message('closing', {});\n",
" fig.ws.close()\n",
"}\n",
"\n",
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
" // Turn the data on the canvas into data in the output cell.\n",
" var dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Tell IPython that the notebook contents must change.\n",
" IPython.notebook.set_dirty(true);\n",
" this.send_message(\"ack\", {});\n",
" var fig = this;\n",
" // Wait a second, then push the new image to the DOM so\n",
" // that it is saved nicely (might be nice to debounce this).\n",
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('<div/>')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items){\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) { continue; };\n",
"\n",
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" // Add the status bar.\n",
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-danger\" href=\"#\" title=\"Close figure\"><i class=\"fa fa-times icon-remove icon-large\"></i></button>');\n",
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
" button.mouseover('Close figure', toolbar_mouse_event);\n",
" buttongrp.append(button);\n",
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
" titlebar.prepend(buttongrp);\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
" // this is important to make the div 'focusable\n",
" el.attr('tabindex', 0)\n",
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
" // off when our div gets focus\n",
"\n",
" // location in version 3\n",
" if (IPython.notebook.keyboard_manager) {\n",
" IPython.notebook.keyboard_manager.register_events(el);\n",
" }\n",
" else {\n",
" // location in version 2\n",
" IPython.keyboard_manager.register_events(el);\n",
" }\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" var manager = IPython.notebook.keyboard_manager;\n",
" if (!manager)\n",
" manager = IPython.keyboard_manager;\n",
"\n",
" // Check for shift+enter\n",
" if (event.shiftKey && event.which == 13) {\n",
" this.canvas_div.blur();\n",
" event.shiftKey = false;\n",
" // Send a \"J\" for go to next cell\n",
" event.which = 74;\n",
" event.keyCode = 74;\n",
" manager.command_mode();\n",
" manager.handle_keydown(event);\n",
" }\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" fig.ondownload(fig, null);\n",
"}\n",
"\n",
"\n",
"mpl.find_output_cell = function(html_output) {\n",
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
" // IPython event is triggered only after the cells have been serialised, which for\n",
" // our purposes (turning an active figure into a static one), is too late.\n",
" var cells = IPython.notebook.get_cells();\n",
" var ncells = cells.length;\n",
" for (var i=0; i<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 3 moved mimebundle to data attribute of output\n",
" data = data.data;\n",
" }\n",
" if (data['text/html'] == html_output) {\n",
" return [cell, data, j];\n",
" }\n",
" }\n",
" }\n",
" }\n",
"}\n",
"\n",
"// Register the function which deals with the matplotlib target/channel.\n",
"// The kernel may be null if the page has been refreshed.\n",
"if (IPython.notebook.kernel != null) {\n",
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
"}\n"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"(-1, 10)"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"fig = plt.figure(figsize=(12,4))\n",
"plt.plot(bw_aors, 'o')\n",
"plt.plot(bw_aors_mireval, 'ro')\n",
"plt.ylim([0.7,0.9])\n",
"plt.xlim([-1, 10])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h2>With greedy note matching</h2>"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"<module 'mir_eval' from '/Users/justin/Documents/dev/mir_eval/mir_eval/__init__.pyc'>"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"reload(me)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"allscores_greedy = []\n",
"names_greedy = []\n",
"\n",
"for reffile, estfile in zip(reffiles, estfiles):\n",
" \n",
" assert (os.path.basename(reffile).split(\"_\"))[0] == (os.path.basename(estfile).split(\"_\"))[0]\n",
" \n",
" ref_int, ref_pitch = me.io.load_valued_intervals(reffile, delimiter=',')\n",
" est_int, est_pitch = me.io.load_valued_intervals(estfile)\n",
" scores = me.transcription.evaluate(ref_int, ref_pitch, est_int, est_pitch)\n",
" allscores_greedy.append(scores)\n",
" names_greedy.append((os.path.basename(reffile).split(\"_\"))[0])"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"bw_aors_greedy = bw['Ave. Overlap'][:10]\n",
"bw_aors_mireval_greedy = [s['Average_Overlap_Ratio'] for s in allscores_greedy]"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\n",
"\n",
"mpl.get_websocket_type = function() {\n",
" if (typeof(WebSocket) !== 'undefined') {\n",
" return WebSocket;\n",
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
" return MozWebSocket;\n",
" } else {\n",
" alert('Your browser does not have WebSocket support.' +\n",
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
" 'Firefox 4 and 5 are also supported but you ' +\n",
" 'have to enable WebSockets in about:config.');\n",
" };\n",
"}\n",
"\n",
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
" this.id = figure_id;\n",
"\n",
" this.ws = websocket;\n",
"\n",
" this.supports_binary = (this.ws.binaryType != undefined);\n",
"\n",
" if (!this.supports_binary) {\n",
" var warnings = document.getElementById(\"mpl-warnings\");\n",
" if (warnings) {\n",
" warnings.style.display = 'block';\n",
" warnings.textContent = (\n",
" \"This browser does not support binary websocket messages. \" +\n",
" \"Performance may be slow.\");\n",
" }\n",
" }\n",
"\n",
" this.imageObj = new Image();\n",
"\n",
" this.context = undefined;\n",
" this.message = undefined;\n",
" this.canvas = undefined;\n",
" this.rubberband_canvas = undefined;\n",
" this.rubberband_context = undefined;\n",
" this.format_dropdown = undefined;\n",
"\n",
" this.image_mode = 'full';\n",
"\n",
" this.root = $('<div/>');\n",
" this._root_extra_style(this.root)\n",
" this.root.attr('style', 'display: inline-block');\n",
"\n",
" $(parent_element).append(this.root);\n",
"\n",
" this._init_header(this);\n",
" this._init_canvas(this);\n",
" this._init_toolbar(this);\n",
"\n",
" var fig = this;\n",
"\n",
" this.waiting = false;\n",
"\n",
" this.ws.onopen = function () {\n",
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
" fig.send_message(\"send_image_mode\", {});\n",
" fig.send_message(\"refresh\", {});\n",
" }\n",
"\n",
" this.imageObj.onload = function() {\n",
" if (fig.image_mode == 'full') {\n",
" // Full images could contain transparency (where diff images\n",
" // almost always do), so we need to clear the canvas so that\n",
" // there is no ghosting.\n",
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
" }\n",
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
" fig.waiting = false;\n",
" };\n",
"\n",
" this.imageObj.onunload = function() {\n",
" this.ws.close();\n",
" }\n",
"\n",
" this.ws.onmessage = this._make_on_message_function(this);\n",
"\n",
" this.ondownload = ondownload;\n",
"}\n",
"\n",
"mpl.figure.prototype._init_header = function() {\n",
" var titlebar = $(\n",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\n",
" titlebar.append(titletext)\n",
" this.root.append(titlebar);\n",
" this.header = titletext[0];\n",
"}\n",
"\n",
"\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._init_canvas = function() {\n",
" var fig = this;\n",
"\n",
" var canvas_div = $('<div/>');\n",
"\n",
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
"\n",
" function canvas_keyboard_event(event) {\n",
" return fig.key_event(event, event['data']);\n",
" }\n",
"\n",
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
" this.canvas_div = canvas_div\n",
" this._canvas_extra_style(canvas_div)\n",
" this.root.append(canvas_div);\n",
"\n",
" var canvas = $('<canvas/>');\n",
" canvas.addClass('mpl-canvas');\n",
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
"\n",
" this.canvas = canvas[0];\n",
" this.context = canvas[0].getContext(\"2d\");\n",
"\n",
" var rubberband = $('<canvas/>');\n",
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
"\n",
" var pass_mouse_events = true;\n",
"\n",
" canvas_div.resizable({\n",
" start: function(event, ui) {\n",
" pass_mouse_events = false;\n",
" },\n",
" resize: function(event, ui) {\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" stop: function(event, ui) {\n",
" pass_mouse_events = true;\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" });\n",
"\n",
" function mouse_event_fn(event) {\n",
" if (pass_mouse_events)\n",
" return fig.mouse_event(event, event['data']);\n",
" }\n",
"\n",
" rubberband.mousedown('button_press', mouse_event_fn);\n",
" rubberband.mouseup('button_release', mouse_event_fn);\n",
" // Throttle sequential mouse events to 1 every 20ms.\n",
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
"\n",
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
"\n",
" canvas_div.on(\"wheel\", function (event) {\n",
" event = event.originalEvent;\n",
" event['data'] = 'scroll'\n",
" if (event.deltaY < 0) {\n",
" event.step = 1;\n",
" } else {\n",
" event.step = -1;\n",
" }\n",
" mouse_event_fn(event);\n",
" });\n",
"\n",
" canvas_div.append(canvas);\n",
" canvas_div.append(rubberband);\n",
"\n",
" this.rubberband = rubberband;\n",
" this.rubberband_canvas = rubberband[0];\n",
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
" this.rubberband_context.strokeStyle = \"#000000\";\n",
"\n",
" this._resize_canvas = function(width, height) {\n",
" // Keep the size of the canvas, canvas container, and rubber band\n",
" // canvas in synch.\n",
" canvas_div.css('width', width)\n",
" canvas_div.css('height', height)\n",
"\n",
" canvas.attr('width', width);\n",
" canvas.attr('height', height);\n",
"\n",
" rubberband.attr('width', width);\n",
" rubberband.attr('height', height);\n",
" }\n",
"\n",
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
" // upon first draw.\n",
" this._resize_canvas(600, 600);\n",
"\n",
" // Disable right mouse context menu.\n",
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
" return false;\n",
" });\n",
"\n",
" function set_focus () {\n",
" canvas.focus();\n",
" canvas_div.focus();\n",
" }\n",
"\n",
" window.setTimeout(set_focus, 100);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('<div/>')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items) {\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) {\n",
" // put a spacer in here.\n",
" continue;\n",
" }\n",
" var button = $('<button/>');\n",
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
" 'ui-button-icon-only');\n",
" button.attr('role', 'button');\n",
" button.attr('aria-disabled', 'false');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
"\n",
" var icon_img = $('<span/>');\n",
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
" icon_img.addClass(image);\n",
" icon_img.addClass('ui-corner-all');\n",
"\n",
" var tooltip_span = $('<span/>');\n",
" tooltip_span.addClass('ui-button-text');\n",
" tooltip_span.html(tooltip);\n",
"\n",
" button.append(icon_img);\n",
" button.append(tooltip_span);\n",
"\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" var fmt_picker_span = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\n",
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
" fmt_picker_span.append(fmt_picker);\n",
" nav_element.append(fmt_picker_span);\n",
" this.format_dropdown = fmt_picker[0];\n",
"\n",
" for (var ind in mpl.extensions) {\n",
" var fmt = mpl.extensions[ind];\n",
" var option = $(\n",
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
" fmt_picker.append(option)\n",
" }\n",
"\n",
" // Add hover states to the ui-buttons\n",
" $( \".ui-button\" ).hover(\n",
" function() { $(this).addClass(\"ui-state-hover\");},\n",
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
" );\n",
"\n",
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"}\n",
"\n",
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
" // which will in turn request a refresh of the image.\n",
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
"}\n",
"\n",
"mpl.figure.prototype.send_message = function(type, properties) {\n",
" properties['type'] = type;\n",
" properties['figure_id'] = this.id;\n",
" this.ws.send(JSON.stringify(properties));\n",
"}\n",
"\n",
"mpl.figure.prototype.send_draw_message = function() {\n",
" if (!this.waiting) {\n",
" this.waiting = true;\n",
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
" }\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" var format_dropdown = fig.format_dropdown;\n",
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
" fig.ondownload(fig, format);\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
" var size = msg['size'];\n",
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
" fig._resize_canvas(size[0], size[1]);\n",
" fig.send_message(\"refresh\", {});\n",
" };\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
" var x0 = msg['x0'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\n",
" x0 = Math.floor(x0) + 0.5;\n",
" y0 = Math.floor(y0) + 0.5;\n",
" x1 = Math.floor(x1) + 0.5;\n",
" y1 = Math.floor(y1) + 0.5;\n",
" var min_x = Math.min(x0, x1);\n",
" var min_y = Math.min(y0, y1);\n",
" var width = Math.abs(x1 - x0);\n",
" var height = Math.abs(y1 - y0);\n",
"\n",
" fig.rubberband_context.clearRect(\n",
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
"\n",
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
" // Updates the figure title.\n",
" fig.header.textContent = msg['label'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
" var cursor = msg['cursor'];\n",
" switch(cursor)\n",
" {\n",
" case 0:\n",
" cursor = 'pointer';\n",
" break;\n",
" case 1:\n",
" cursor = 'default';\n",
" break;\n",
" case 2:\n",
" cursor = 'crosshair';\n",
" break;\n",
" case 3:\n",
" cursor = 'move';\n",
" break;\n",
" }\n",
" fig.rubberband_canvas.style.cursor = cursor;\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
" fig.message.textContent = msg['message'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
" // Request the server to send over a new figure.\n",
" fig.send_draw_message();\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
" fig.image_mode = msg['mode'];\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Called whenever the canvas gets updated.\n",
" this.send_message(\"ack\", {});\n",
"}\n",
"\n",
"// A function to construct a web socket function for onmessage handling.\n",
"// Called in the figure constructor.\n",
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
" return function socket_on_message(evt) {\n",
" if (evt.data instanceof Blob) {\n",
" /* FIXME: We get \"Resource interpreted as Image but\n",
" * transferred with MIME type text/plain:\" errors on\n",
" * Chrome. But how to set the MIME type? It doesn't seem\n",
" * to be part of the websocket stream */\n",
" evt.data.type = \"image/png\";\n",
"\n",
" /* Free the memory for the previous frames */\n",
" if (fig.imageObj.src) {\n",
" (window.URL || window.webkitURL).revokeObjectURL(\n",
" fig.imageObj.src);\n",
" }\n",
"\n",
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
" evt.data);\n",
" fig.updated_canvas_event();\n",
" return;\n",
" }\n",
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
" fig.imageObj.src = evt.data;\n",
" fig.updated_canvas_event();\n",
" return;\n",
" }\n",
"\n",
" var msg = JSON.parse(evt.data);\n",
" var msg_type = msg['type'];\n",
"\n",
" // Call the \"handle_{type}\" callback, which takes\n",
" // the figure and JSON message as its only arguments.\n",
" try {\n",
" var callback = fig[\"handle_\" + msg_type];\n",
" } catch (e) {\n",
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
" return;\n",
" }\n",
"\n",
" if (callback) {\n",
" try {\n",
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
" callback(fig, msg);\n",
" } catch (e) {\n",
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
" }\n",
" }\n",
" };\n",
"}\n",
"\n",
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
"mpl.findpos = function(e) {\n",
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
" var targ;\n",
" if (!e)\n",
" e = window.event;\n",
" if (e.target)\n",
" targ = e.target;\n",
" else if (e.srcElement)\n",
" targ = e.srcElement;\n",
" if (targ.nodeType == 3) // defeat Safari bug\n",
" targ = targ.parentNode;\n",
"\n",
" // jQuery normalizes the pageX and pageY\n",
" // pageX,Y are the mouse positions relative to the document\n",
" // offset() returns the position of the element relative to the document\n",
" var x = e.pageX - $(targ).offset().left;\n",
" var y = e.pageY - $(targ).offset().top;\n",
"\n",
" return {\"x\": x, \"y\": y};\n",
"};\n",
"\n",
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
" var canvas_pos = mpl.findpos(event)\n",
"\n",
" if (name === 'button_press')\n",
" {\n",
" this.canvas.focus();\n",
" this.canvas_div.focus();\n",
" }\n",
"\n",
" var x = canvas_pos.x;\n",
" var y = canvas_pos.y;\n",
"\n",
" this.send_message(name, {x: x, y: y, button: event.button,\n",
" step: event.step});\n",
"\n",
" /* This prevents the web browser from automatically changing to\n",
" * the text insertion cursor when the button is pressed. We want\n",
" * to control all of the cursor setting manually through the\n",
" * 'cursor' event from matplotlib */\n",
" event.preventDefault();\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" // Handle any extra behaviour associated with a key event\n",
"}\n",
"\n",
"mpl.figure.prototype.key_event = function(event, name) {\n",
"\n",
" // Prevent repeat events\n",
" if (name == 'key_press')\n",
" {\n",
" if (event.which === this._key)\n",
" return;\n",
" else\n",
" this._key = event.which;\n",
" }\n",
" if (name == 'key_release')\n",
" this._key = null;\n",
"\n",
" var value = '';\n",
" if (event.ctrlKey && event.which != 17)\n",
" value += \"ctrl+\";\n",
" if (event.altKey && event.which != 18)\n",
" value += \"alt+\";\n",
" if (event.shiftKey && event.which != 16)\n",
" value += \"shift+\";\n",
"\n",
" value += 'k';\n",
" value += event.which.toString();\n",
"\n",
" this._key_event_extra(event, name);\n",
"\n",
" this.send_message(name, {key: value});\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
" if (name == 'download') {\n",
" this.handle_save(this, null);\n",
" } else {\n",
" this.send_message(\"toolbar_button\", {name: name});\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
" this.message.textContent = tooltip;\n",
"};\n",
"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",
"\n",
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
"\n",
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
" // object with the appropriate methods. Currently this is a non binary\n",
" // socket, so there is still some room for performance tuning.\n",
" var ws = {};\n",
"\n",
" ws.close = function() {\n",
" comm.close()\n",
" };\n",
" ws.send = function(m) {\n",
" //console.log('sending', m);\n",
" comm.send(m);\n",
" };\n",
" // Register the callback with on_msg.\n",
" comm.on_msg(function(msg) {\n",
" //console.log('receiving', msg['content']['data'], msg);\n",
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
" ws.onmessage(msg['content']['data'])\n",
" });\n",
" return ws;\n",
"}\n",
"\n",
"mpl.mpl_figure_comm = function(comm, msg) {\n",
" // This is the function which gets called when the mpl process\n",
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
"\n",
" var id = msg.content.data.id;\n",
" // Get hold of the div created by the display call when the Comm\n",
" // socket was opened in Python.\n",
" var element = $(\"#\" + id);\n",
" var ws_proxy = comm_websocket_adapter(comm)\n",
"\n",
" function ondownload(figure, format) {\n",
" window.open(figure.imageObj.src);\n",
" }\n",
"\n",
" var fig = new mpl.figure(id, ws_proxy,\n",
" ondownload,\n",
" element.get(0));\n",
"\n",
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
" // web socket which is closed, not our websocket->open comm proxy.\n",
" ws_proxy.onopen();\n",
"\n",
" fig.parent_element = element.get(0);\n",
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
" if (!fig.cell_info) {\n",
" console.error(\"Failed to find cell for figure\", id, fig);\n",
" return;\n",
" }\n",
"\n",
" var output_index = fig.cell_info[2]\n",
" var cell = fig.cell_info[0];\n",
"\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
" // Update the output cell to use the data from the current canvas.\n",
" fig.push_to_output();\n",
" var dataURL = fig.canvas.toDataURL();\n",
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
" // the notebook keyboard shortcuts fail.\n",
" IPython.keyboard_manager.enable()\n",
" $(fig.parent_element).html('<img src=\"' + dataURL + '\">');\n",
" fig.send_message('closing', {});\n",
" fig.ws.close()\n",
"}\n",
"\n",
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
" // Turn the data on the canvas into data in the output cell.\n",
" var dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Tell IPython that the notebook contents must change.\n",
" IPython.notebook.set_dirty(true);\n",
" this.send_message(\"ack\", {});\n",
" var fig = this;\n",
" // Wait a second, then push the new image to the DOM so\n",
" // that it is saved nicely (might be nice to debounce this).\n",
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('<div/>')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items){\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) { continue; };\n",
"\n",
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" // Add the status bar.\n",
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-danger\" href=\"#\" title=\"Close figure\"><i class=\"fa fa-times icon-remove icon-large\"></i></button>');\n",
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
" button.mouseover('Close figure', toolbar_mouse_event);\n",
" buttongrp.append(button);\n",
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
" titlebar.prepend(buttongrp);\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
" // this is important to make the div 'focusable\n",
" el.attr('tabindex', 0)\n",
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
" // off when our div gets focus\n",
"\n",
" // location in version 3\n",
" if (IPython.notebook.keyboard_manager) {\n",
" IPython.notebook.keyboard_manager.register_events(el);\n",
" }\n",
" else {\n",
" // location in version 2\n",
" IPython.keyboard_manager.register_events(el);\n",
" }\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" var manager = IPython.notebook.keyboard_manager;\n",
" if (!manager)\n",
" manager = IPython.keyboard_manager;\n",
"\n",
" // Check for shift+enter\n",
" if (event.shiftKey && event.which == 13) {\n",
" this.canvas_div.blur();\n",
" event.shiftKey = false;\n",
" // Send a \"J\" for go to next cell\n",
" event.which = 74;\n",
" event.keyCode = 74;\n",
" manager.command_mode();\n",
" manager.handle_keydown(event);\n",
" }\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" fig.ondownload(fig, null);\n",
"}\n",
"\n",
"\n",
"mpl.find_output_cell = function(html_output) {\n",
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
" // IPython event is triggered only after the cells have been serialised, which for\n",
" // our purposes (turning an active figure into a static one), is too late.\n",
" var cells = IPython.notebook.get_cells();\n",
" var ncells = cells.length;\n",
" for (var i=0; i<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 3 moved mimebundle to data attribute of output\n",
" data = data.data;\n",
" }\n",
" if (data['text/html'] == html_output) {\n",
" return [cell, data, j];\n",
" }\n",
" }\n",
" }\n",
" }\n",
"}\n",
"\n",
"// Register the function which deals with the matplotlib target/channel.\n",
"// The kernel may be null if the page has been refreshed.\n",
"if (IPython.notebook.kernel != null) {\n",
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
"}\n"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"(-1, 10)"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"fig = plt.figure(figsize=(12,4))\n",
"plt.plot(bw_aors_greedy, 'o')\n",
"plt.plot(bw_aors_mireval_greedy, 'ro')\n",
"plt.ylim([0.7,0.9])\n",
"plt.xlim([-1, 10])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h2>How much does AOR change for different algorithms?</h2>"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"-0.038179308750744156"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"bw2_diffs = (bw_aors_mireval - bw_aors)\n",
"np.mean(bw2_diffs)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def get_scores(refffiles, estfiles):\n",
"\n",
" allscores = []\n",
" names = []\n",
"\n",
" for reffile, estfile in zip(reffiles, estfiles):\n",
"\n",
" assert (os.path.basename(reffile).split(\"_\"))[0] == (os.path.basename(estfile).split(\"_\"))[0]\n",
"\n",
" ref_int, ref_pitch = me.io.load_valued_intervals(reffile, delimiter=',')\n",
" est_int, est_pitch = me.io.load_valued_intervals(estfile)\n",
" scores = me.transcription.evaluate(ref_int, ref_pitch, est_int, est_pitch)\n",
" allscores.append(scores)\n",
" names.append((os.path.basename(reffile).split(\"_\"))[0])\n",
" \n",
" return allscores, names"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/justin/Documents/dev/mir_eval/mir_eval/io.py:438: UserWarning: All interval durations must be strictly positive\n",
" warnings.warn(error.args[0])\n"
]
}
],
"source": [
"alglist = ['BW2', 'BW3', 'CB1', 'CB2', 'SY1', 'SY2', 'SY3', 'SY4']\n",
"\n",
"alldiffs = []\n",
"\n",
"for algname in alglist:\n",
" \n",
" algfile = '/Users/justin/datasets/transcription/MIREX_2015_Su_dataset/results_mirex_2015/%s/%s.results.csv' % (algname, algname)\n",
" alg = pd.read_csv(algfile)\n",
" alg = alg.fillna(0)\n",
" \n",
" estfolder = '/Users/justin/datasets/transcription/MIREX_2015_Su_dataset/alg_output_mirex_2015/algo_note/%s/' % (algname)\n",
" estfiles = glob.glob(os.path.join(estfolder, \"*.txt\"))\n",
" \n",
" allscores, names = get_scores(reffiles, estfiles)\n",
" \n",
" alg_aors = alg['Ave. Overlap'][:10]\n",
" alg_aors_mireval = [s['Average_Overlap_Ratio'] for s in allscores]\n",
" \n",
" alg_diffs = (alg_aors_mireval - alg_aors)\n",
" alldiffs.append(alg_diffs)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.text.Text at 0x1103af7d0>"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x110368190>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig = plt.figure(figsize=(12,4))\n",
"for d in alldiffs:\n",
" plt.plot(d, 'o')\n",
"plt.xlabel('track')\n",
"plt.ylabel('AOR difference = mir_eval - MIREX')"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ds = []\n",
"for d in alldiffs:\n",
" ds.extend(d.values)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/png": "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\ndQAAAABJRU5ErkJggg==\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x11070e610>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig = plt.figure()\n",
"plt.boxplot(ds, showmeans=True)\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.8"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment