Permalink
Browse files

Lots of work on plugins - new d3 graph plotting, reorg.

  • Loading branch information...
1 parent d84e28d commit e2cefa37774183680b34bdbc614fb86bb138170c @ellisonbg ellisonbg committed Nov 9, 2012
View
@@ -0,0 +1,14 @@
+# d3 Plugin
+
+This plugin adds d3.js to the IPython Notebook, so it can be used by other plugins.
+
+# Installation
+
+To install this plugin:
+
+1. Move the `d3` directory into the `static/jsplugins` directory of one of your IPython profiles.
+
+# Usage
+
+This plugin isn't used by itself. To use d3, other plugins must be written that use d3.
+
File renamed without changes.
View
@@ -0,0 +1,17 @@
+# Displaying graphs using d3
+
+This JS plugin enables NetworkX graphs to be visualized using d3's force directed layout
+algorithm.
+
+# Installation
+
+To install this plugin:
+
+1. First install the d3 plugin (see its README).
+2. Move the `d3graph` directory into the `static/jsplugins` directory of one of your IPython profiles.
+3. Move the `.py` files in the `python` directory somewhere on your `PYTHONPATH`. One possible location is `~.ipython/extensions`.
+
+# Usage
+
+Have a look at the IPython Notebook in this directory for an example.
+
@@ -0,0 +1,67 @@
+{
+ "metadata": {
+ "name": "Visualizing Graphs with d3"
+ },
+ "nbformat": 3,
+ "nbformat_minor": 0,
+ "worksheets": [
+ {
+ "cells": [
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "%load_ext d3graph"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 8
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "import networkx as nx\n",
+ "from IPython.display import display"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 9
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "G = nx.generators.random_geometric_graph(20,0.3)"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 20
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "display(G)"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 21
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [],
+ "language": "python",
+ "metadata": {},
+ "outputs": []
+ }
+ ],
+ "metadata": {}
+ }
+ ]
+}
View
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+"""
+D3 Graph visualizations for NetworkX.
+
+Authors:
+* Brian Granger
+"""
+#-----------------------------------------------------------------------------
+# Copyright (C) 2012, IPython Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+#-----------------------------------------------------------------------------
+
+from IPython.core.displaypub import publish_json
+
+import networkx as nx
+from networkx.readwrite import json_graph
+
+from zmq.utils import jsonapi
+
+def graph_to_json(G):
+ d = json_graph.node_link_data(G) # node-link format to serialize
+ d['handler'] = 'd3graph'
+ data = jsonapi.dumps(d)
+ return data
+
+_loaded = False
+
+def load_ipython_extension(ip):
+ """Load the extension in IPython."""
+
+ global _loaded
+ if not _loaded:
+ json_formatter = ip.display_formatter.formatters['application/json']
+
+ json_formatter.for_type_by_name(
+ 'networkx.classes.graph', 'Graph', graph_to_json
+ )
+ _loaded = True
@@ -0,0 +1,9 @@
+circle.node {
+ stroke: #fff;
+ stroke-width: 1.5px;
+}
+
+line.link {
+ stroke: #999;
+ stroke-opacity: .6;
+}
@@ -0,0 +1,62 @@
+var d3graph_json_handler = function (json, element) {
+ var id = 'd3graph-'+IPython.utils.uuid();
+ var toinsert = $("<div/>").attr('id',id);
+ element.append(toinsert);
+
+ var w = 400;
+ var h = 400;
+ var fill = d3.scale.category20();
+
+ var vis = d3.select('#'+id)
+ .append("svg:svg")
+ .attr("width", w)
+ .attr("height", h);
+
+ var force = d3.layout.force()
+ .charge(-120)
+ .linkDistance(30)
+ .nodes(json.nodes)
+ .links(json.links)
+ .size([w, h])
+ .start();
+
+ var link = vis.selectAll("line.link")
+ .data(json.links)
+ .enter().append("svg:line")
+ .attr("class", "link")
+ .style("stroke-width", function(d) { return Math.sqrt(d.value); })
+ .attr("x1", function(d) { return d.source.x; })
+ .attr("y1", function(d) { return d.source.y; })
+ .attr("x2", function(d) { return d.target.x; })
+ .attr("y2", function(d) { return d.target.y; });
+
+ var node = vis.selectAll("circle.node")
+ .data(json.nodes)
+ .enter().append("svg:circle")
+ .attr("class", "node")
+ .attr("cx", function(d) { return d.x; })
+ .attr("cy", function(d) { return d.y; })
+ .attr("r", 5)
+ .style("fill", function(d) { return fill(d.group); })
+ .call(force.drag);
+
+ node.append("svg:title")
+ .text(function(d) { return d.name; });
+
+ vis.style("opacity", 1e-6)
+ .transition()
+ .duration(1000)
+ .style("opacity", 1);
+
+ force.on("tick", function() {
+ link.attr("x1", function(d) { return d.source.x; })
+ .attr("y1", function(d) { return d.source.y; })
+ .attr("x2", function(d) { return d.target.x; })
+ .attr("y2", function(d) { return d.target.y; });
+
+ node.attr("cx", function(d) { return d.x; })
+ .attr("cy", function(d) { return d.y; });
+ });
+};
+
+IPython.json_handlers.register_handler('d3graph', d3graph_json_handler)
Oops, something went wrong.

0 comments on commit e2cefa3

Please sign in to comment.