{ "cells": [ { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "# Draft 2" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "**Node and Edge Attributes** \n", "In from_networkx, NetworkX's node/edge attributes are converted for GraphRenderer's node_renderer/edge_renderer. \n", "For example, \"Zachary's Karate Club graph\" dataset has a node attribute named \"club\". It's possible to hover these information using the node attributes converted in from_networkx. Similarly, node/edge attributes can also be used for color information.\n", "\n", "Here’s a graph example that hovers node attributes and changes colors with edge attributes:" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "ExecuteTime": { "end_time": "2018-10-01T13:19:01.371894Z", "start_time": "2018-10-01T13:19:00.648985Z" }, "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "G has node attributes. For example, {'club': 'Mr. Hi'}\n", "G has edge attributes. For example, {'edge_color': 'black'}\n" ] }, { "data": { "text/html": [ "\n", "
\n", " \n", " Loading BokehJS ...\n", "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "\n", "(function(root) {\n", " function now() {\n", " return new Date();\n", " }\n", "\n", " var force = true;\n", "\n", " if (typeof (root._bokeh_onload_callbacks) === \"undefined\" || force === true) {\n", " root._bokeh_onload_callbacks = [];\n", " root._bokeh_is_loading = undefined;\n", " }\n", "\n", " var JS_MIME_TYPE = 'application/javascript';\n", " var HTML_MIME_TYPE = 'text/html';\n", " var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", " var CLASS_NAME = 'output_bokeh rendered_html';\n", "\n", " /**\n", " * Render data to the DOM node\n", " */\n", " function render(props, node) {\n", " var script = document.createElement(\"script\");\n", " node.appendChild(script);\n", " }\n", "\n", " /**\n", " * Handle when an output is cleared or removed\n", " */\n", " function handleClearOutput(event, handle) {\n", " var cell = handle.cell;\n", "\n", " var id = cell.output_area._bokeh_element_id;\n", " var server_id = cell.output_area._bokeh_server_id;\n", " // Clean up Bokeh references\n", " if (id != null && id in Bokeh.index) {\n", " Bokeh.index[id].model.document.clear();\n", " delete Bokeh.index[id];\n", " }\n", "\n", " if (server_id !== undefined) {\n", " // Clean up Bokeh references\n", " var cmd = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", " cell.notebook.kernel.execute(cmd, {\n", " iopub: {\n", " output: function(msg) {\n", " var id = msg.content.text.trim();\n", " if (id in Bokeh.index) {\n", " Bokeh.index[id].model.document.clear();\n", " delete Bokeh.index[id];\n", " }\n", " }\n", " }\n", " });\n", " // Destroy server and session\n", " var cmd = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", " cell.notebook.kernel.execute(cmd);\n", " }\n", " }\n", "\n", " /**\n", " * Handle when a new output is added\n", " */\n", " function handleAddOutput(event, handle) {\n", " var output_area = handle.output_area;\n", " var output = handle.output;\n", "\n", " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", " if ((output.output_type != \"display_data\") || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", " return\n", " }\n", "\n", " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", "\n", " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", " // store reference to embed id on output_area\n", " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", " }\n", " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", " var bk_div = document.createElement(\"div\");\n", " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", " var script_attrs = bk_div.children[0].attributes;\n", " for (var i = 0; i < script_attrs.length; i++) {\n", " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", " }\n", " // store reference to server id on output_area\n", " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", " }\n", " }\n", "\n", " function register_renderer(events, OutputArea) {\n", "\n", " function append_mime(data, metadata, element) {\n", " // create a DOM node to render to\n", " var toinsert = this.create_output_subarea(\n", " metadata,\n", " CLASS_NAME,\n", " EXEC_MIME_TYPE\n", " );\n", " this.keyboard_manager.register_events(toinsert);\n", " // Render to node\n", " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", " render(props, toinsert[toinsert.length - 1]);\n", " element.append(toinsert);\n", " return toinsert\n", " }\n", "\n", " /* Handle when an output is cleared or removed */\n", " events.on('clear_output.CodeCell', handleClearOutput);\n", " events.on('delete.Cell', handleClearOutput);\n", "\n", " /* Handle when a new output is added */\n", " events.on('output_added.OutputArea', handleAddOutput);\n", "\n", " /**\n", " * Register the mime type and append_mime function with output_area\n", " */\n", " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", " /* Is output safe? */\n", " safe: true,\n", " /* Index of renderer in `output_area.display_order` */\n", " index: 0\n", " });\n", " }\n", "\n", " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", " if (root.Jupyter !== undefined) {\n", " var events = require('base/js/events');\n", " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", "\n", " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", " register_renderer(events, OutputArea);\n", " }\n", " }\n", "\n", " \n", " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", " root._bokeh_timeout = Date.now() + 5000;\n", " root._bokeh_failed_load = false;\n", " }\n", "\n", " var NB_LOAD_WARNING = {'data': {'text/html':\n", " \"
\\n\"+\n", " \"

\\n\"+\n", " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", " \"

\\n\"+\n", " \"\\n\"+\n", " \"\\n\"+\n", " \"from bokeh.resources import INLINE\\n\"+\n", " \"output_notebook(resources=INLINE)\\n\"+\n", " \"\\n\"+\n", " \"
\"}};\n", "\n", " function display_loaded() {\n", " var el = document.getElementById(\"9207b336-f040-452e-a5b5-d365cf49e154\");\n", " if (el != null) {\n", " el.textContent = \"BokehJS is loading...\";\n", " }\n", " if (root.Bokeh !== undefined) {\n", " if (el != null) {\n", " el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n", " }\n", " } else if (Date.now() < root._bokeh_timeout) {\n", " setTimeout(display_loaded, 100)\n", " }\n", " }\n", "\n", "\n", " function run_callbacks() {\n", " try {\n", " root._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n", " }\n", " finally {\n", " delete root._bokeh_onload_callbacks\n", " }\n", " console.info(\"Bokeh: all callbacks have finished\");\n", " }\n", "\n", " function load_libs(js_urls, callback) {\n", " root._bokeh_onload_callbacks.push(callback);\n", " if (root._bokeh_is_loading > 0) {\n", " console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", " return null;\n", " }\n", " if (js_urls == null || js_urls.length === 0) {\n", " run_callbacks();\n", " return null;\n", " }\n", " console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", " root._bokeh_is_loading = js_urls.length;\n", " for (var i = 0; i < js_urls.length; i++) {\n", " var url = js_urls[i];\n", " var s = document.createElement('script');\n", " s.src = url;\n", " s.async = false;\n", " s.onreadystatechange = s.onload = function() {\n", " root._bokeh_is_loading--;\n", " if (root._bokeh_is_loading === 0) {\n", " console.log(\"Bokeh: all BokehJS libraries loaded\");\n", " run_callbacks()\n", " }\n", " };\n", " s.onerror = function() {\n", " console.warn(\"failed to load library \" + url);\n", " };\n", " console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.getElementsByTagName(\"head\")[0].appendChild(s);\n", " }\n", " };var element = document.getElementById(\"9207b336-f040-452e-a5b5-d365cf49e154\");\n", " if (element == null) {\n", " console.log(\"Bokeh: ERROR: autoload.js configured with elementid '9207b336-f040-452e-a5b5-d365cf49e154' but no matching script tag was found. \")\n", " return false;\n", " }\n", "\n", " var js_urls = [\"https://cdn.pydata.org/bokeh/dev/bokeh-1.0.0dev9.min.js\", \"https://cdn.pydata.org/bokeh/dev/bokeh-widgets-1.0.0dev9.min.js\", \"https://cdn.pydata.org/bokeh/dev/bokeh-tables-1.0.0dev9.min.js\", \"https://cdn.pydata.org/bokeh/dev/bokeh-gl-1.0.0dev9.min.js\"];\n", "\n", " var inline_js = [\n", " function(Bokeh) {\n", " Bokeh.set_log_level(\"info\");\n", " },\n", " \n", " function(Bokeh) {\n", " \n", " },\n", " function(Bokeh) {\n", " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/dev/bokeh-1.0.0dev9.min.css\");\n", " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/dev/bokeh-1.0.0dev9.min.css\");\n", " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/dev/bokeh-widgets-1.0.0dev9.min.css\");\n", " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/dev/bokeh-widgets-1.0.0dev9.min.css\");\n", " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/dev/bokeh-tables-1.0.0dev9.min.css\");\n", " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/dev/bokeh-tables-1.0.0dev9.min.css\");\n", " }\n", " ];\n", "\n", " function run_inline_js() {\n", " \n", " if ((root.Bokeh !== undefined) || (force === true)) {\n", " for (var i = 0; i < inline_js.length; i++) {\n", " inline_js[i].call(root, root.Bokeh);\n", " }if (force === true) {\n", " display_loaded();\n", " }} else if (Date.now() < root._bokeh_timeout) {\n", " setTimeout(run_inline_js, 100);\n", " } else if (!root._bokeh_failed_load) {\n", " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", " root._bokeh_failed_load = true;\n", " } else if (force !== true) {\n", " var cell = $(document.getElementById(\"9207b336-f040-452e-a5b5-d365cf49e154\")).parents('.cell').data().cell;\n", " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", " }\n", "\n", " }\n", "\n", " if (root._bokeh_is_loading === 0) {\n", " console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", " run_inline_js();\n", " } else {\n", " load_libs(js_urls, function() {\n", " console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n", " run_inline_js();\n", " });\n", " }\n", "}(window));" ], "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof (root._bokeh_onload_callbacks) === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n \n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"9207b336-f040-452e-a5b5-d365cf49e154\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n }\n finally {\n delete root._bokeh_onload_callbacks\n }\n console.info(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(js_urls, callback) {\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = js_urls.length;\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var s = document.createElement('script');\n s.src = url;\n s.async = false;\n s.onreadystatechange = s.onload = function() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.log(\"Bokeh: all BokehJS libraries loaded\");\n run_callbacks()\n }\n };\n s.onerror = function() {\n console.warn(\"failed to load library \" + url);\n };\n console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.getElementsByTagName(\"head\")[0].appendChild(s);\n }\n };var element = document.getElementById(\"9207b336-f040-452e-a5b5-d365cf49e154\");\n if (element == null) {\n console.log(\"Bokeh: ERROR: autoload.js configured with elementid '9207b336-f040-452e-a5b5-d365cf49e154' but no matching script tag was found. \")\n return false;\n }\n\n var js_urls = [\"https://cdn.pydata.org/bokeh/dev/bokeh-1.0.0dev9.min.js\", \"https://cdn.pydata.org/bokeh/dev/bokeh-widgets-1.0.0dev9.min.js\", \"https://cdn.pydata.org/bokeh/dev/bokeh-tables-1.0.0dev9.min.js\", \"https://cdn.pydata.org/bokeh/dev/bokeh-gl-1.0.0dev9.min.js\"];\n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n \n function(Bokeh) {\n \n },\n function(Bokeh) {\n console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/dev/bokeh-1.0.0dev9.min.css\");\n Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/dev/bokeh-1.0.0dev9.min.css\");\n console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/dev/bokeh-widgets-1.0.0dev9.min.css\");\n Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/dev/bokeh-widgets-1.0.0dev9.min.css\");\n console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/dev/bokeh-tables-1.0.0dev9.min.css\");\n Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/dev/bokeh-tables-1.0.0dev9.min.css\");\n }\n ];\n\n function run_inline_js() {\n \n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"9207b336-f040-452e-a5b5-d365cf49e154\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(js_urls, function() {\n console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "
\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "(function(root) {\n", " function embed_document(root) {\n", " \n", " var docs_json = {\"8621faf9-5125-483d-b6ca-9ca68024e611\":{\"roots\":{\"references\":[{\"attributes\":{\"plot_height\":400,\"plot_width\":400,\"renderers\":[{\"id\":\"df697440-856a-4b64-afae-3807b33f9a22\",\"type\":\"BoxAnnotation\"},{\"id\":\"75456b91-4720-4d53-963e-845d84fca330\",\"type\":\"GraphRenderer\"}],\"title\":{\"id\":\"b3c9b08e-3f30-45de-b2d9-96c082dccbe7\",\"type\":\"Title\"},\"toolbar\":{\"id\":\"c9959696-4055-4289-8be2-1f026c99a584\",\"type\":\"Toolbar\"},\"x_range\":{\"id\":\"bfd4925c-b6f6-449e-a79d-95aba5e7fc25\",\"type\":\"Range1d\"},\"x_scale\":{\"id\":\"9bf97794-2266-4919-acb3-66eb7199207b\",\"type\":\"LinearScale\"},\"y_range\":{\"id\":\"eab523d8-4dde-414f-95dc-ef3c8d5cecd4\",\"type\":\"Range1d\"},\"y_scale\":{\"id\":\"e16f816c-5e1d-4dd8-bf7a-8fbdb3457b4f\",\"type\":\"LinearScale\"}},\"id\":\"a90f8be5-fe69-49a8-b7a2-de866855f710\",\"type\":\"Plot\"},{\"attributes\":{\"callback\":null,\"data\":{\"edge_color\":[\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"red\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"red\",\"black\",\"black\",\"black\",\"red\",\"black\",\"red\",\"red\",\"red\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"red\",\"red\",\"red\",\"black\",\"red\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"red\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\",\"black\"],\"end\":[1,2,3,4,5,6,7,8,10,11,12,13,17,19,21,31,2,3,7,13,17,19,21,30,3,7,8,9,13,27,28,32,7,12,13,6,10,6,10,16,16,30,32,33,33,33,32,33,32,33,32,33,33,32,33,32,33,25,27,29,32,33,25,27,31,31,29,33,33,31,33,32,33,32,33,32,33,33],\"start\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,4,4,5,5,5,6,8,8,8,9,13,14,14,15,15,18,18,19,20,20,22,22,23,23,23,23,23,24,24,24,25,26,26,27,28,28,29,29,30,30,31,31,32]},\"selected\":{\"id\":\"d0a2d335-7781-4bfe-ba71-72ac3f79f341\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1b0c6676-044e-4c84-a35d-f10d977d24aa\",\"type\":\"UnionRenderers\"}},\"id\":\"9e3a47b3-429e-4127-bf56-eaf8a7ef48b3\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"callback\":null,\"renderers\":\"auto\",\"tooltips\":[[\"index\",\"@index\"],[\"club\",\"@club\"]]},\"id\":\"3c444f95-ecc1-4cde-a5f2-580534696687\",\"type\":\"HoverTool\"},{\"attributes\":{\"source\":{\"id\":\"9e3a47b3-429e-4127-bf56-eaf8a7ef48b3\",\"type\":\"ColumnDataSource\"}},\"id\":\"8a7aee4f-fd43-4461-8a6d-c73cde56af78\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"a2766cd8-18e2-4f7e-8958-f32a41618a0b\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"9bf97794-2266-4919-acb3-66eb7199207b\",\"type\":\"LinearScale\"},{\"attributes\":{\"callback\":null,\"end\":1.1,\"start\":-1.1},\"id\":\"eab523d8-4dde-414f-95dc-ef3c8d5cecd4\",\"type\":\"Range1d\"},{\"attributes\":{\"source\":{\"id\":\"2599b5f3-4e8f-4b7c-92d4-55bdcfb8dba5\",\"type\":\"ColumnDataSource\"}},\"id\":\"5ec541de-7078-4833-8733-8c87668c8082\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"2599b5f3-4e8f-4b7c-92d4-55bdcfb8dba5\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2d5131ee-3e07-4fb4-a736-4bc8f4aba020\",\"type\":\"Circle\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"5ec541de-7078-4833-8733-8c87668c8082\",\"type\":\"CDSView\"}},\"id\":\"9501e288-8e88-41e1-a054-e9d1583eb084\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"value\":\"#2b83ba\"},\"size\":{\"units\":\"screen\",\"value\":15}},\"id\":\"2d5131ee-3e07-4fb4-a736-4bc8f4aba020\",\"type\":\"Circle\"},{\"attributes\":{\"plot\":null,\"text\":\"Graph Interaction Demonstration\"},\"id\":\"b3c9b08e-3f30-45de-b2d9-96c082dccbe7\",\"type\":\"Title\"},{\"attributes\":{\"edge_renderer\":{\"id\":\"ab9236ef-d61a-4631-9333-1154557b9379\",\"type\":\"GlyphRenderer\"},\"inspection_policy\":{\"id\":\"b76c0217-d934-4727-ab47-7f5df72f014a\",\"type\":\"NodesOnly\"},\"layout_provider\":{\"id\":\"d0971fe2-12cd-4e06-9fc8-fa1bcd62726e\",\"type\":\"StaticLayoutProvider\"},\"node_renderer\":{\"id\":\"9501e288-8e88-41e1-a054-e9d1583eb084\",\"type\":\"GlyphRenderer\"},\"selection_policy\":{\"id\":\"d4669f95-af1e-4487-a898-5509af40822a\",\"type\":\"NodesOnly\"}},\"id\":\"75456b91-4720-4d53-963e-845d84fca330\",\"type\":\"GraphRenderer\"},{\"attributes\":{},\"id\":\"d0a2d335-7781-4bfe-ba71-72ac3f79f341\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"d0b42c00-3ac4-4d28-bb95-5ffdce013226\",\"type\":\"Selection\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_multi\":null,\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"3c444f95-ecc1-4cde-a5f2-580534696687\",\"type\":\"HoverTool\"},{\"id\":\"fdd03d50-5140-40ff-a4aa-453c9e375564\",\"type\":\"BoxZoomTool\"},{\"id\":\"0a5b49af-63ea-48f3-a7ac-8bf2c381cabf\",\"type\":\"ResetTool\"}]},\"id\":\"c9959696-4055-4289-8be2-1f026c99a584\",\"type\":\"Toolbar\"},{\"attributes\":{\"line_alpha\":{\"value\":0.8},\"line_color\":{\"field\":\"edge_color\"}},\"id\":\"60a58fc8-666c-406f-b9ca-e5bac866c9bf\",\"type\":\"MultiLine\"},{\"attributes\":{},\"id\":\"d4669f95-af1e-4487-a898-5509af40822a\",\"type\":\"NodesOnly\"},{\"attributes\":{},\"id\":\"b76c0217-d934-4727-ab47-7f5df72f014a\",\"type\":\"NodesOnly\"},{\"attributes\":{\"overlay\":{\"id\":\"df697440-856a-4b64-afae-3807b33f9a22\",\"type\":\"BoxAnnotation\"}},\"id\":\"fdd03d50-5140-40ff-a4aa-453c9e375564\",\"type\":\"BoxZoomTool\"},{\"attributes\":{\"data_source\":{\"id\":\"9e3a47b3-429e-4127-bf56-eaf8a7ef48b3\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"60a58fc8-666c-406f-b9ca-e5bac866c9bf\",\"type\":\"MultiLine\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"8a7aee4f-fd43-4461-8a6d-c73cde56af78\",\"type\":\"CDSView\"}},\"id\":\"ab9236ef-d61a-4631-9333-1154557b9379\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1b0c6676-044e-4c84-a35d-f10d977d24aa\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"bottom_units\":\"screen\",\"fill_alpha\":{\"value\":0.5},\"fill_color\":{\"value\":\"lightgrey\"},\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":{\"value\":1.0},\"line_color\":{\"value\":\"black\"},\"line_dash\":[4,4],\"line_width\":{\"value\":2},\"plot\":null,\"render_mode\":\"css\",\"right_units\":\"screen\",\"top_units\":\"screen\"},\"id\":\"df697440-856a-4b64-afae-3807b33f9a22\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"callback\":null,\"end\":1.1,\"start\":-1.1},\"id\":\"bfd4925c-b6f6-449e-a79d-95aba5e7fc25\",\"type\":\"Range1d\"},{\"attributes\":{\"graph_layout\":{\"0\":[-0.318890284128364,-0.15424668150232382],\"1\":[-0.1661111615524047,-0.10585425346133762],\"10\":[-0.614621721499768,-0.35957605143230226],\"11\":[-0.45960658612887123,-0.5134111224951896],\"12\":[-0.5276584753392278,0.06551453676098896],\"13\":[-0.10709263518889887,0.06200031720539653],\"14\":[0.4486715421226663,0.3865363754831786],\"15\":[0.30692292388320025,0.4975729104949169],\"16\":[-1.0,-0.2579744148965742],\"17\":[-0.3532420477255095,-0.32685563553084374],\"18\":[0.5434426838985194,0.3785510830172775],\"19\":[-0.011905335297541118,-0.11118490989037821],\"2\":[0.01834335970564624,-0.011192179731921973],\"20\":[0.20135014596149234,0.46306333900559304],\"21\":[-0.22772857632525823,-0.37934082672914415],\"22\":[0.41605993873365266,0.4859555706968516],\"23\":[0.519708107481401,0.061554666101050114],\"24\":[0.45735348432232253,-0.29070229002044434],\"25\":[0.5481425422844431,-0.18350079402342268],\"26\":[0.691300713639903,0.24711921264016656],\"27\":[0.3832163391901555,-0.06888793765317752],\"28\":[0.23517205981489753,0.032368903311537404],\"29\":[0.5572933952245908,0.21503775123418198],\"3\":[-0.29445868024595345,0.05207514454145844],\"30\":[0.055215791911710936,0.20848122335049282],\"31\":[0.20413812234952075,-0.08960423530012779],\"32\":[0.29452520631146795,0.2496491775477824],\"33\":[0.2964878576286684,0.17636896453974482],\"4\":[-0.6200602150729077,-0.22323434388927754],\"5\":[-0.7441695397713654,-0.27973566795656646],\"6\":[-0.7521308200100084,-0.16856974479118916],\"7\":[-0.26566044074830664,-0.03695030524180235],\"8\":[0.009728211887595796,0.1165064987010986],\"9\":[0.2762640926825275,-0.1375342800856921]}},\"id\":\"d0971fe2-12cd-4e06-9fc8-fa1bcd62726e\",\"type\":\"StaticLayoutProvider\"},{\"attributes\":{},\"id\":\"e16f816c-5e1d-4dd8-bf7a-8fbdb3457b4f\",\"type\":\"LinearScale\"},{\"attributes\":{},\"id\":\"0a5b49af-63ea-48f3-a7ac-8bf2c381cabf\",\"type\":\"ResetTool\"},{\"attributes\":{\"callback\":null,\"data\":{\"club\":[\"Mr. Hi\",\"Mr. Hi\",\"Mr. Hi\",\"Mr. Hi\",\"Mr. Hi\",\"Mr. Hi\",\"Mr. Hi\",\"Mr. Hi\",\"Mr. Hi\",\"Officer\",\"Mr. Hi\",\"Mr. Hi\",\"Mr. Hi\",\"Mr. Hi\",\"Officer\",\"Officer\",\"Mr. Hi\",\"Mr. Hi\",\"Officer\",\"Mr. Hi\",\"Officer\",\"Mr. Hi\",\"Officer\",\"Officer\",\"Officer\",\"Officer\",\"Officer\",\"Officer\",\"Officer\",\"Officer\",\"Officer\",\"Officer\",\"Officer\",\"Officer\"],\"index\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33]},\"selected\":{\"id\":\"d0b42c00-3ac4-4d28-bb95-5ffdce013226\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"a2766cd8-18e2-4f7e-8958-f32a41618a0b\",\"type\":\"UnionRenderers\"}},\"id\":\"2599b5f3-4e8f-4b7c-92d4-55bdcfb8dba5\",\"type\":\"ColumnDataSource\"}],\"root_ids\":[\"a90f8be5-fe69-49a8-b7a2-de866855f710\"]},\"title\":\"Bokeh Application\",\"version\":\"1.0.0dev9\"}};\n", " var render_items = [{\"docid\":\"8621faf9-5125-483d-b6ca-9ca68024e611\",\"roots\":{\"a90f8be5-fe69-49a8-b7a2-de866855f710\":\"c0055e24-d3cb-4c46-bb51-b9ac64ff5f7c\"}}];\n", " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", "\n", " }\n", " if (root.Bokeh !== undefined) {\n", " embed_document(root);\n", " } else {\n", " var attempts = 0;\n", " var timer = setInterval(function(root) {\n", " if (root.Bokeh !== undefined) {\n", " embed_document(root);\n", " clearInterval(timer);\n", " }\n", " attempts++;\n", " if (attempts > 100) {\n", " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", " clearInterval(timer);\n", " }\n", " }, 10, root)\n", " }\n", "})(window);" ], "application/vnd.bokehjs_exec.v0+json": "" }, "metadata": { "application/vnd.bokehjs_exec.v0+json": { "id": "a90f8be5-fe69-49a8-b7a2-de866855f710" } }, "output_type": "display_data" } ], "source": [ "import networkx as nx\n", "\n", "from bokeh.io import show, output_file, output_notebook, output_file\n", "from bokeh.models import Plot, Range1d, MultiLine, Circle, HoverTool, BoxZoomTool, ResetTool\n", "from bokeh.models.graphs import from_networkx\n", "from bokeh.palettes import Spectral4\n", "\n", "# Prepare Data\n", "G = nx.karate_club_graph()\n", "\n", "SAME_CLUB_COLOR, DIFFERENT_CLUB_COLOR = \"black\", \"red\"\n", "edge_attrs = {}\n", "\n", "for start_node, end_node, _ in G.edges(data=True):\n", " edge_color = SAME_CLUB_COLOR if G.nodes[start_node][\"club\"] == G.nodes[end_node][\"club\"] else DIFFERENT_CLUB_COLOR\n", " edge_attrs[(start_node, end_node)] = edge_color\n", "\n", "nx.set_edge_attributes(G, edge_attrs, \"edge_color\")\n", "\n", "print(\"G has node attributes. For example, {}\".format(G.nodes[0]))\n", "print(\"G has edge attributes. For example, {}\".format(G.edges[(0, 1)]))\n", "\n", "# Show with Bokeh\n", "plot = Plot(plot_width=400, plot_height=400,\n", " x_range=Range1d(-1.1, 1.1), y_range=Range1d(-1.1, 1.1))\n", "plot.title.text = \"Graph Interaction Demonstration\"\n", "\n", "node_hover_tool = HoverTool(tooltips=[(\"index\", \"@index\"), (\"club\", \"@club\")])\n", "plot.add_tools(node_hover_tool, BoxZoomTool(), ResetTool())\n", "\n", "graph_renderer = from_networkx(G, nx.spring_layout, scale=1, center=(0,0))\n", "\n", "graph_renderer.node_renderer.glyph = Circle(size=15, fill_color=Spectral4[0])\n", "graph_renderer.edge_renderer.glyph = MultiLine(line_color=\"edge_color\", line_alpha=0.8, line_width=1)\n", "plot.renderers.append(graph_renderer)\n", "\n", "# This code will be change to \"output_file(\"interactive_graphs.html\")\n", "# output_file(\"interactive_graphs.html\")\n", "output_notebook()\n", "show(plot)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "hide_input": false, "kernelspec": { "display_name": "Environment (conda_nx2_env)", "language": "python", "name": "conda_nx2_env" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.2" }, "toc": { "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": false, "toc_cell": false, "toc_position": {}, "toc_section_display": "block", "toc_window_display": false }, "varInspector": { "cols": { "lenName": 16, "lenType": 16, "lenVar": 40 }, "kernels_config": { "python": { "delete_cmd_postfix": "", "delete_cmd_prefix": "del ", "library": "var_list.py", "varRefreshCmd": "print(var_dic_list())" }, "r": { "delete_cmd_postfix": ") ", "delete_cmd_prefix": "rm(", "library": "var_list.r", "varRefreshCmd": "cat(var_dic_list()) " } }, "types_to_exclude": [ "module", "function", "builtin_function_or_method", "instance", "_Feature" ], "window_display": false } }, "nbformat": 4, "nbformat_minor": 2 }