Skip to content

Instantly share code, notes, and snippets.

@Midnighter
Last active August 29, 2015 13:56
Show Gist options
  • Save Midnighter/8906987 to your computer and use it in GitHub Desktop.
Save Midnighter/8906987 to your computer and use it in GitHub Desktop.
{
"metadata": {
"name": ""
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "code",
"collapsed": false,
"input": [
"# stdlib\n",
"import os\n",
"import json\n",
"# external\n",
"import networkx as nx\n",
"import networkx.readwrite.json_graph as nx_json\n",
"import vincent"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 1
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"vincent.core.initialize_notebook()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"javascript": [
"\n",
" if (window['d3'] === undefined) {\n",
" require.config({ paths: {d3: \"http://d3js.org/d3.v3.min\"} });\n",
" require([\"d3\"], function(d3) {\n",
" window.d3 = d3;\n",
" $.getScript(\"http://d3js.org/d3.geo.projection.v0.min.js\", function() {\n",
" $.getScript(\"http://wrobstory.github.io/d3-cloud/d3.layout.cloud.js\", function() {\n",
" $.getScript(\"http://d3js.org/topojson.v1.min.js\", function() {\n",
" $.getScript(\"http://trifacta.github.com/vega/vega.js\", function() {\n",
" $([IPython.events]).trigger(\"vega_loaded.vincent\");\n",
" })\n",
" })\n",
" })\n",
" });\n",
" });\n",
" };\n",
" "
],
"metadata": {},
"output_type": "display_data",
"text": [
"<IPython.core.display.Javascript at 0x1eb1090>"
]
}
],
"prompt_number": 2
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def vega_example(json_path):\n",
" \"\"\"wrap a JSON graph representation in JSON that allows vega display.\"\"\"\n",
" vega_json = {\n",
" \"name\": \"force\",\n",
" \"width\": 500,\n",
" \"height\": 500,\n",
" \"padding\": {\"top\":0, \"bottom\":0, \"left\":0, \"right\":0},\n",
" \"data\": [\n",
" {\n",
" \"name\": \"edges\",\n",
" \"url\": \"\",\n",
" \"format\": {\"type\": \"json\", \"property\": \"links\"},\n",
" \"transform\": [\n",
" {\"type\": \"copy\", \"from\": \"data\", \"fields\": [\"source\", \"target\"]}\n",
" ]\n",
" },\n",
" {\n",
" \"name\": \"nodes\",\n",
" \"url\": \"\",\n",
" \"format\": {\"type\": \"json\", \"property\": \"nodes\"},\n",
" \"transform\": [\n",
" {\n",
" \"type\": \"force\",\n",
" \"links\": \"edges\",\n",
" \"linkDistance\": 70,\n",
" \"charge\": -100,\n",
" \"iterations\": 1000\n",
" }\n",
" ]\n",
" }\n",
" ],\n",
" \"marks\": [\n",
" {\n",
" \"type\": \"path\",\n",
" \"from\": {\n",
" \"data\": \"edges\",\n",
" \"transform\": [\n",
" {\"type\": \"link\", \"shape\": \"line\"}\n",
" ]\n",
" },\n",
" \"properties\": {\n",
" \"update\": {\n",
" \"path\": {\"field\": \"path\"},\n",
" \"stroke\": {\"value\": \"#ccc\"},\n",
" \"strokeWidth\": {\"value\": 0.5}\n",
" }\n",
" }\n",
" },\n",
" {\n",
" \"type\": \"symbol\",\n",
" \"from\": {\"data\": \"nodes\"},\n",
" \"properties\": {\n",
" \"enter\": {\n",
" \"fillOpacity\": {\"value\": 0.3},\n",
" \"stroke\": {\"value\": \"steelblue\"}\n",
" },\n",
" \"update\": {\n",
" \"x\": {\"field\": \"x\"},\n",
" \"y\": {\"field\": \"y\"},\n",
" \"fill\": {\"value\": \"steelblue\"}\n",
" },\n",
" \"hover\": {\n",
" \"fill\": {\"value\": \"#f00\"}\n",
" }\n",
" }\n",
" }\n",
" ]\n",
" }\n",
" vega_json[\"data\"][0][\"url\"] = os.path.join(\"files\", json_path)\n",
" vega_json[\"data\"][1][\"url\"] = os.path.join(\"files\", json_path)\n",
" return vega_json"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 3
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def display(json):\n",
" \"\"\"Display visualization inline in IPython notebook\"\"\"\n",
" from IPython.core.display import display, HTML, Javascript\n",
" from uuid import uuid4\n",
"\n",
" # Copied from vincent.ipynb:\n",
" # HACK: use a randomly chosen unique div id\n",
" id = str(uuid4())\n",
" a = HTML('<div id=\"vis%s\"></div>' % id)\n",
" b = Javascript(_vega_t % (json, id))\n",
" display(a, b)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 4
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"_vega_t = \"\"\"\n",
"( function() {\n",
" var _do_plot = function() {\n",
" if ( typeof vg == 'undefined' ) {\n",
" $([IPython.events]).on(\"vega_loaded.vincent\", _do_plot);\n",
" return;\n",
" }\n",
" vg.parse.spec(%s, function(chart) {\n",
" chart({el: \"#vis%s\"}).update();\n",
" });\n",
" };\n",
" _do_plot();\n",
"})();\n",
"\"\"\""
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 5
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"display(vega_example(\"miserables.json\"))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div id=\"visc2e8e20f-ab60-455b-9409-baf46b83b88b\"></div>"
],
"metadata": {},
"output_type": "display_data",
"text": [
"<IPython.core.display.HTML at 0x28e9810>"
]
},
{
"javascript": [
"\n",
"( function() {\n",
" var _do_plot = function() {\n",
" if ( typeof vg == 'undefined' ) {\n",
" $([IPython.events]).on(\"vega_loaded.vincent\", _do_plot);\n",
" return;\n",
" }\n",
" vg.parse.spec({'name': 'force', 'height': 500, 'padding': {'top': 0, 'left': 0, 'right': 0, 'bottom': 0}, 'width': 500, 'marks': [{'from': {'data': 'edges', 'transform': [{'shape': 'line', 'type': 'link'}]}, 'type': 'path', 'properties': {'update': {'path': {'field': 'path'}, 'stroke': {'value': '#ccc'}, 'strokeWidth': {'value': 0.5}}}}, {'from': {'data': 'nodes'}, 'type': 'symbol', 'properties': {'hover': {'fill': {'value': '#f00'}}, 'update': {'y': {'field': 'y'}, 'x': {'field': 'x'}, 'fill': {'value': 'steelblue'}}, 'enter': {'stroke': {'value': 'steelblue'}, 'fillOpacity': {'value': 0.3}}}}], 'data': [{'url': 'files/miserables.json', 'transform': [{'from': 'data', 'type': 'copy', 'fields': ['source', 'target']}], 'name': 'edges', 'format': {'property': 'links', 'type': 'json'}}, {'url': 'files/miserables.json', 'transform': [{'iterations': 1000, 'charge': -100, 'type': 'force', 'linkDistance': 70, 'links': 'edges'}], 'name': 'nodes', 'format': {'property': 'nodes', 'type': 'json'}}]}, function(chart) {\n",
" chart({el: \"#visc2e8e20f-ab60-455b-9409-baf46b83b88b\"}).update();\n",
" });\n",
" };\n",
" _do_plot();\n",
"})();\n"
],
"metadata": {},
"output_type": "display_data",
"text": [
"<IPython.core.display.Javascript at 0x28e9850>"
]
}
],
"prompt_number": 6
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"kar_g = nx.karate_club_graph()\n",
"json.dump(nx_json.node_link_data(kar_g), open(\"karate.json\", \"w\"))"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 7
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"display(vega_example(\"karate.json\"))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div id=\"vis5c8d02fb-92ca-4c06-ba28-53016ab761a5\"></div>"
],
"metadata": {},
"output_type": "display_data",
"text": [
"<IPython.core.display.HTML at 0x28e97d0>"
]
},
{
"javascript": [
"\n",
"( function() {\n",
" var _do_plot = function() {\n",
" if ( typeof vg == 'undefined' ) {\n",
" $([IPython.events]).on(\"vega_loaded.vincent\", _do_plot);\n",
" return;\n",
" }\n",
" vg.parse.spec({'name': 'force', 'height': 500, 'padding': {'top': 0, 'left': 0, 'right': 0, 'bottom': 0}, 'width': 500, 'marks': [{'from': {'data': 'edges', 'transform': [{'shape': 'line', 'type': 'link'}]}, 'type': 'path', 'properties': {'update': {'path': {'field': 'path'}, 'stroke': {'value': '#ccc'}, 'strokeWidth': {'value': 0.5}}}}, {'from': {'data': 'nodes'}, 'type': 'symbol', 'properties': {'hover': {'fill': {'value': '#f00'}}, 'update': {'y': {'field': 'y'}, 'x': {'field': 'x'}, 'fill': {'value': 'steelblue'}}, 'enter': {'stroke': {'value': 'steelblue'}, 'fillOpacity': {'value': 0.3}}}}], 'data': [{'url': 'files/karate.json', 'transform': [{'from': 'data', 'type': 'copy', 'fields': ['source', 'target']}], 'name': 'edges', 'format': {'property': 'links', 'type': 'json'}}, {'url': 'files/karate.json', 'transform': [{'iterations': 1000, 'charge': -100, 'type': 'force', 'linkDistance': 70, 'links': 'edges'}], 'name': 'nodes', 'format': {'property': 'nodes', 'type': 'json'}}]}, function(chart) {\n",
" chart({el: \"#vis5c8d02fb-92ca-4c06-ba28-53016ab761a5\"}).update();\n",
" });\n",
" };\n",
" _do_plot();\n",
"})();\n"
],
"metadata": {},
"output_type": "display_data",
"text": [
"<IPython.core.display.Javascript at 0x28e9810>"
]
}
],
"prompt_number": 8
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"simple = nx.Graph(name=\"test\")\n",
"simple.add_edge(1, 2)\n",
"simple.add_edge(1, 3)\n",
"simple.add_edge(3, 2)\n",
"json.dump(nx_json.node_link_data(simple), open(\"simple.json\", \"w\"))"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 9
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"display(vega_example(\"simple.json\"))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div id=\"vis77e1c009-f591-465e-bcbd-0c0eebc5444b\"></div>"
],
"metadata": {},
"output_type": "display_data",
"text": [
"<IPython.core.display.HTML at 0x28e95d0>"
]
},
{
"javascript": [
"\n",
"( function() {\n",
" var _do_plot = function() {\n",
" if ( typeof vg == 'undefined' ) {\n",
" $([IPython.events]).on(\"vega_loaded.vincent\", _do_plot);\n",
" return;\n",
" }\n",
" vg.parse.spec({'name': 'force', 'height': 500, 'padding': {'top': 0, 'left': 0, 'right': 0, 'bottom': 0}, 'width': 500, 'marks': [{'from': {'data': 'edges', 'transform': [{'shape': 'line', 'type': 'link'}]}, 'type': 'path', 'properties': {'update': {'path': {'field': 'path'}, 'stroke': {'value': '#ccc'}, 'strokeWidth': {'value': 0.5}}}}, {'from': {'data': 'nodes'}, 'type': 'symbol', 'properties': {'hover': {'fill': {'value': '#f00'}}, 'update': {'y': {'field': 'y'}, 'x': {'field': 'x'}, 'fill': {'value': 'steelblue'}}, 'enter': {'stroke': {'value': 'steelblue'}, 'fillOpacity': {'value': 0.3}}}}], 'data': [{'url': 'files/simple.json', 'transform': [{'from': 'data', 'type': 'copy', 'fields': ['source', 'target']}], 'name': 'edges', 'format': {'property': 'links', 'type': 'json'}}, {'url': 'files/simple.json', 'transform': [{'iterations': 1000, 'charge': -100, 'type': 'force', 'linkDistance': 70, 'links': 'edges'}], 'name': 'nodes', 'format': {'property': 'nodes', 'type': 'json'}}]}, function(chart) {\n",
" chart({el: \"#vis77e1c009-f591-465e-bcbd-0c0eebc5444b\"}).update();\n",
" });\n",
" };\n",
" _do_plot();\n",
"})();\n"
],
"metadata": {},
"output_type": "display_data",
"text": [
"<IPython.core.display.Javascript at 0x28e9710>"
]
}
],
"prompt_number": 10
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from itertools import izip, count\n",
"from vincent.core import grammar, _assert_is_type\n",
"from vincent._compat import str_types\n",
"\n",
"@grammar(str_types)\n",
"def shape(value):\n",
" \"\"\"\n",
" \"\"\"\n",
"vincent.Transform.shape = shape\n",
"\n",
"@grammar(grammar_type=vincent.ValueRef, grammar_name='strokeWidth')\n",
"def stroke_width(value):\n",
" \"\"\"ValueRef : float, width of the stroke in pixels\n",
" \"\"\"\n",
" if value.value:\n",
" _assert_is_type('stroke_width.value', value.value, float)\n",
" if value.value < 0:\n",
" raise ValueError('stroke width cannot be negative')\n",
"vincent.PropertySet.stroke_width = stroke_width\n",
"\n",
"class Graph(vincent.Visualization):\n",
" def __init__(self, graph, width=500, height=500, weight=\"weight\", **kw_args):\n",
" super(Graph, self).__init__(**kw_args)\n",
" self.width = int(width)\n",
" self.height = int(height)\n",
" self.padding = dict(top=10, bottom=10, left=10, right=10)\n",
" self.name = graph.name # if graph.name else \"NX Graph\"\n",
" nx_nodes = sorted(graph.nodes())\n",
" node2id = dict(izip(nx_nodes, count()))\n",
" edges = vincent.Data(name=\"edges\")\n",
" edges.values = [dict(source=node2id[u], target=node2id[v]) for (u, v, d) in graph.edges_iter(data=True)]\n",
" edges.transform = [vincent.Transform(type=\"copy\", from_=\"data\", fields=[\"source\", \"target\"])]\n",
" self.data.append(edges)\n",
" nodes = vincent.Data(name=\"nodes\")\n",
" nodes.values = [dict(name=str(n)) for n in nx_nodes]\n",
" nodes.transform = [vincent.Transform(type=\"force\", links=\"edges\", iterations=1000, charge=-100,\n",
" link_distance=70, link_strength=100)]\n",
" self.data.append(nodes)\n",
" mark = vincent.Mark(type=\"path\",\n",
" from_=vincent.MarkRef(data=\"edges\", transform=[vincent.Transform(type=\"link\", shape=\"line\")]),\n",
" properties=vincent.MarkProperties(update=vincent.PropertySet(\n",
" path=vincent.ValueRef(field=\"path\"),\n",
" stroke=vincent.ValueRef(value=\"#ccc\"),\n",
" stroke_width=vincent.ValueRef(value=0.5)\n",
" )\n",
" )\n",
" )\n",
" self.marks.append(mark)\n",
" mark = vincent.Mark(type=\"symbol\",\n",
" from_=vincent.MarkRef(data=\"nodes\"),\n",
" properties=vincent.MarkProperties(enter=vincent.PropertySet(\n",
" fill_opacity=vincent.ValueRef(value=0.3),\n",
" stroke=vincent.ValueRef(value=\"steelblue\")\n",
" ),\n",
" update=vincent.PropertySet(\n",
" x=vincent.ValueRef(field=\"x\"),\n",
" y=vincent.ValueRef(field=\"y\"),\n",
" fill=vincent.ValueRef(value=\"steelblue\")\n",
" ),\n",
" hover=vincent.PropertySet(fill=vincent.ValueRef(value=\"#f00\"))\n",
" )\n",
" )\n",
" self.marks.append(mark)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 11
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"graph = Graph(simple)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 12
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"graph.display()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div id=\"vis59997\"></div>"
],
"metadata": {},
"output_type": "display_data",
"text": [
"<IPython.core.display.HTML at 0x28e9fd0>"
]
},
{
"javascript": [
"\n",
"( function() {\n",
" var _do_plot = function() {\n",
" if ( typeof vg == 'undefined' ) {\n",
" $([IPython.events]).on(\"vega_loaded.vincent\", _do_plot);\n",
" return;\n",
" }\n",
" vg.parse.spec({\"axes\": [], \"data\": [{\"name\": \"edges\", \"transform\": [{\"fields\": [\"source\", \"target\"], \"from\": \"data\", \"type\": \"copy\"}], \"values\": [{\"source\": 0, \"target\": 1}, {\"source\": 0, \"target\": 2}, {\"source\": 1, \"target\": 2}]}, {\"name\": \"nodes\", \"transform\": [{\"charge\": -100, \"iterations\": 1000, \"linkDistance\": 70, \"linkStrength\": 100, \"links\": \"edges\", \"type\": \"force\"}], \"values\": [{\"name\": \"1\"}, {\"name\": \"2\"}, {\"name\": \"3\"}]}], \"height\": 500, \"legends\": [], \"marks\": [{\"from\": {\"data\": \"edges\", \"transform\": [{\"shape\": \"line\", \"type\": \"link\"}]}, \"properties\": {\"update\": {\"path\": {\"field\": \"path\"}, \"stroke\": {\"value\": \"#ccc\"}, \"strokeWidth\": {\"value\": 0.5}}}, \"type\": \"path\"}, {\"from\": {\"data\": \"nodes\"}, \"properties\": {\"enter\": {\"fillOpacity\": {\"value\": 0.3}, \"stroke\": {\"value\": \"steelblue\"}}, \"hover\": {\"fill\": {\"value\": \"#f00\"}}, \"update\": {\"fill\": {\"value\": \"steelblue\"}, \"x\": {\"field\": \"x\"}, \"y\": {\"field\": \"y\"}}}, \"type\": \"symbol\"}], \"name\": \"test\", \"padding\": {\"bottom\": 10, \"left\": 10, \"right\": 10, \"top\": 10}, \"scales\": [], \"width\": 500}, function(chart) {\n",
" chart({el: \"#vis59997\"}).update();\n",
" });\n",
" };\n",
" _do_plot();\n",
"})();\n"
],
"metadata": {},
"output_type": "display_data",
"text": [
"<IPython.core.display.Javascript at 0x28e9590>"
]
}
],
"prompt_number": 13
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"print graph.to_json()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"{\n",
" \"axes\": [],\n",
" \"data\": [\n",
" {\n",
" \"name\": \"edges\",\n",
" \"transform\": [\n",
" {\n",
" \"fields\": [\n",
" \"source\",\n",
" \"target\"\n",
" ],\n",
" \"from\": \"data\",\n",
" \"type\": \"copy\"\n",
" }\n",
" ],\n",
" \"values\": [\n",
" {\n",
" \"source\": 0,\n",
" \"target\": 1\n",
" },\n",
" {\n",
" \"source\": 0,\n",
" \"target\": 2\n",
" },\n",
" {\n",
" \"source\": 1,\n",
" \"target\": 2\n",
" }\n",
" ]\n",
" },\n",
" {\n",
" \"name\": \"nodes\",\n",
" \"transform\": [\n",
" {\n",
" \"charge\": -100,\n",
" \"iterations\": 1000,\n",
" \"linkDistance\": 70,\n",
" \"linkStrength\": 100,\n",
" \"links\": \"edges\",\n",
" \"type\": \"force\"\n",
" }\n",
" ],\n",
" \"values\": [\n",
" {\n",
" \"name\": \"1\"\n",
" },\n",
" {\n",
" \"name\": \"2\"\n",
" },\n",
" {\n",
" \"name\": \"3\"\n",
" }\n",
" ]\n",
" }\n",
" ],\n",
" \"height\": 500,\n",
" \"legends\": [],\n",
" \"marks\": [\n",
" {\n",
" \"from\": {\n",
" \"data\": \"edges\",\n",
" \"transform\": [\n",
" {\n",
" \"shape\": \"line\",\n",
" \"type\": \"link\"\n",
" }\n",
" ]\n",
" },\n",
" \"properties\": {\n",
" \"update\": {\n",
" \"path\": {\n",
" \"field\": \"path\"\n",
" },\n",
" \"stroke\": {\n",
" \"value\": \"#ccc\"\n",
" },\n",
" \"strokeWidth\": {\n",
" \"value\": 0.5\n",
" }\n",
" }\n",
" },\n",
" \"type\": \"path\"\n",
" },\n",
" {\n",
" \"from\": {\n",
" \"data\": \"nodes\"\n",
" },\n",
" \"properties\": {\n",
" \"enter\": {\n",
" \"fillOpacity\": {\n",
" \"value\": 0.3\n",
" },\n",
" \"stroke\": {\n",
" \"value\": \"steelblue\"\n",
" }\n",
" },\n",
" \"hover\": {\n",
" \"fill\": {\n",
" \"value\": \"#f00\"\n",
" }\n",
" },\n",
" \"update\": {\n",
" \"fill\": {\n",
" \"value\": \"steelblue\"\n",
" },\n",
" \"x\": {\n",
" \"field\": \"x\"\n",
" },\n",
" \"y\": {\n",
" \"field\": \"y\"\n",
" }\n",
" }\n",
" },\n",
" \"type\": \"symbol\"\n",
" }\n",
" ],\n",
" \"name\": \"test\",\n",
" \"padding\": {\n",
" \"bottom\": 10,\n",
" \"left\": 10,\n",
" \"right\": 10,\n",
" \"top\": 10\n",
" },\n",
" \"scales\": [],\n",
" \"width\": 500\n",
"}\n"
]
}
],
"prompt_number": 14
}
],
"metadata": {}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment