How to visualize a graph using d3.js in iPython notebook? - python

I have a graph that I would like to visualize using d3.js. Specifically, I have an adjacency matrix that looks as follows (selection of data, not the full set):
Node 1 Node 2 Weight
A B 1.0
A C 1.0
A D 1.5
B D 1.0
...
I would like to be able to use a Force-Directed Graph to display my network, specifically.
I know how to create a NetworkX graph, but I would like to be able to try this in d3.js, as I want to be able to add mouseover displays of node properties later on, which I think is possible using d3 but not possible using matplotlib.
I have tried using d3py, but I can't even get the basic example to work, and I read that the NetworkX example is broken and the repo hasn't been updated for a while. Does anybody else know if there's something else I could try, or if someone could point me in a first step direction?

There is a NetworkX example here that uses d3.js force layout :http://networkx.github.io/documentation/latest/examples/javascript/force.html
It just writes a JSON format graph object from networkx that d3.js can load in a web browser to get an interactive drawing. That code is a little fancier since it will also do the web browser part for you.
All of the code (including the d3 parts) you need to run it are in the repository https://github.com/networkx/networkx/tree/master/examples/javascript

If you're fine with an alternative JavaScript framework, we've been building http://www.github.com/graphistry/pygraphistry . The idea is to use WebGL to render the big graphs (pan/zoom/etc.), and offload most of the real-time compute (layout, filter, etc.) to a GPU cloud. There's an API underneath for controlling it similarly to D3. It's easier for most uses however, as it streamlines common big graph manipulations and analyses.

Related

Packages that work with networkx that can handle clickable nodes

I'm looking to try and visualize data using networkx as a network graph. My data looks great, but i'm wanting to add on hover and on click events to display additional information.
For example, there might be a node called "New York", when clicked will display a small table to the side of the canvas that gives information like how many cities, current population, etc.
I'm currently using pyviz with networkx. That seems to be really straightforward as far as creating the graph, but not so much on the kind of user interaction i'm looking for.
I also tried bokeh and plotly, but on the on click and hover functions while work, isn't very straightforward to implement with networkx. Here's a picture of what my graph looks like. My goal is to show relationships between systems.
pyvis graph
I maintain a python library for network visualisations called netgraph, which works nicely with networkx or igraph Graph objects. I thought this was a neat idea for a feature, so I just implemented a bare bones version on the dev branch.
Installation via pip:
pip install https://github.com/paulbrodersen/netgraph/archive/dev.zip
Code to reproduce the example above:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import networkx as nx
from netgraph import InteractiveGraph
g = nx.cubical_graph()
tables = dict()
for node in g.nodes:
data = np.round(np.random.rand(3,2), decimals=2)
table = pd.DataFrame(data, index=['Lorem', 'ipsum', 'dolor'], columns=['sit', 'amet'])
tables[node] = table
for edge in g.edges:
data = np.round(np.random.rand(4,1), decimals=2)
table = pd.DataFrame(data, index=['consectetur', 'adipiscing', 'elit', 'Mauris'], columns=['sed'])
tables[edge] = table
fig, ax = plt.subplots(figsize=(12,5))
fig.subplots_adjust(right=0.6) # make space for table on the right
bbox = [1.5, 0.1, 0.5, 0.8] # position of the table in axes coordinates
instance = InteractiveGraph(g, node_labels=True, tables=tables, table_kwargs=dict(edges='horizontal', fontsize=16, bbox=bbox), ax=ax)
plt.show()
Take a look at the kglab project which is an open source abstraction layer in Python that integrates both NetworkX and PyVis, along with other graph related libraries in Python. It was built for this kind of use case.
There's a class kglab.KnowledgeGraph which has transforms and inverse transforms to work these other libraries:
NetworkX examples https://derwen.ai/docs/kgl/ex6_0/
PyVis examples https://derwen.ai/docs/kgl/ex3_0/
For instance, you could:
build a graph using a KnowledgeGraph object
transform out to run NetworkX graph algorithms
use an inverse transform to populate calculated attributes on the main graph object
transform out to load and run a PyVis interactive session, which in turn can have clickable components
We've got Jupyter notebooks on the GH repo showing each of these steps. plus a developer community where other people can help for a specific use case (create a GH issue)
There is VisDCC, which requires Dash (a kind of data-science server thing).
The end result is a web server serving an HTML canvas that you can insert in a web page, for instance. (This is actually inherited from Vis.js)
VisDCC has almost no documentation but it works (I'm using it) and the usage follows that of Dash which is well-documented. You need to learn to use Dash's #callback format to write the code.
So I guess it's a good enough solution :)

How to draw readable, preferably interactive, network graphs with python?

I'm trying to draw a graph of any network running my script. I use scapy to collect packets and would like to have a node per computer communicating, and an edge per connection.
The issue is I can't find a way to visualize the graph well enough on my screen. So far combining networkx with matlib.pyplot managed to bring the best results, but it still seems pretty random and chaotic, the tags are hard to read, nodes are on top of each other, etc'. It is also preferable to have the ability to interact with the graph - move nodes around, hover over nodes/edges to get extra info, perhaps zoom in or even cluster together nodes so that when you click on the cluster you can see which nodes compose the cluster.
Since analyzing the network data and adding nodes&edges to the graph will be tedious for you to read, I'm adding only the relevant part here (the part that actually shows the graph I built):
pos = nx.spring_layout(Graph, scale=2)
edge_labels = nx.get_edge_attributes(Graph, "Protocol")
nx.draw(Graph,pos, with_labels=True, node_size=600, font_size=8, font_weight='bold')
nx.draw_networkx_edge_labels(Graph, pos, edge_labels=edge_labels, font_size=8)
plt.show()
(I imported networks as nx and matplotlib.pyplot as plt)
I also tried graphviz, ploty and bokeh but couldn't really make them work and after troubleshooting on Google got the impression that anyway they won't fix my problem, and I also tried adjustText - but I could not manage to fit it in my code in any way (can't find how to get the text attribute of my graph) and Holoviews - but it refuses to show an image no matter what I try (even if I copy and paste examples from their site - either python says that '%opts...' is invalid syntax, or if I try changing options any other way the code just runs until it ends and doesn't show anything on the screen.
This is what the graph looks like:
I'm finding a lot of partial solutions online so none of them work, does anybody has a comprehensive solution?
Drawing heavy graphs with plt can be a bit problematic, the problem here is not only with the data, it is also a problem for a human eye to get a lot of information in one look.
My suggestion is to use a more advanced graph visualization library, for example, ipycytoscape. you can define also styles and more features with it that will match your demands
from ipycytoscape import CytoscapeWidget
graph_draw = ipycytoscape.CytoscapeWidget()
graph_draw.graph.add_graph_from_networkx(nx_graph, directed=True)
In addition, if you will use CytoscapeWidget you can interact with the graph and match the focus of the view to the part in the graph that interests you the most.
You can tune the hyper-parameters (k and iterations) of the nx.spring_layout to arrange the nodes. Once you tune the parameters, the connected nodes will be close to each other, and not-contacted nodes will maintain a maximum possible distance.
pos = nx.spring_layout(G,k=0.1, iterations=20)

Python 2.7 NetworkX (Make it interactive)

I am new to NetworkX. Right now, I manage to connect all the nodes to this particular node. What I want to do next it to make it interactive e.g. able to make each of the node move by dragging using cursor. I know I have to make use of matplotlib, but I am not sure how to use it. Can anyone help me?
My codes are:
import matplotlib.pyplot as plt
import networkx as nx
import itertools
d = [name of nodes]
f = [number per nodes]
for i in d:
G.add_edge('"' + i + '"',b)
pos=nx.fruchterman_reingold_layout(G, k=0.5, iterations=5)
nx.draw_networkx_nodes(G,pos,node_size=130, node_color="white")
nx.draw_networkx_edges(G,pos, width=0.2,alpha=1,edge_color='black')
nx.draw_networkx_labels(G,pos,font_size=7,font_family='sans-serif')
for i,j in itertools.izip(d,f):
nx.draw_networkx_edge_labels(G,pos, {('"' + i + '"',b):j}, font_size=7, label_pos= 0.80)
plt.axis('off')
plt.show()
It seems hard to do with matplotlib (it is not really been designed for that). Networkx drawing module is pretty poor it mostly uses a custom scatter plot for nodes, etc.
I suggest another solution:
Export your graph to JSON or GEXF and use a Javascript graph drawing library to make your graph interactive such as: SigmaJs, or VivaGraphJs.
You find an example of a real graph created with NetworkX embedded on a webpage on my blog. Nodes are static in this example but clicking on a node highlights its neighbors.
Official examples for the proposed interactive graph drawing libraries:
List of examples using sigma.js.
Tutorial for VivaGraphJs.
Matplotlib was designed more for static graphs and charts.
However once the NetworkX graph is exported to GEXF format there is a tool which will allow you to select areas based on position or critera in order to move it around. The tool is called Gephi. You can play with the layout to get started or go as deep as data scientists like to get.

Analyze graph using Python Library or create graph using matplotlib

I have got graph which need to analyzed and report an Error.As of Now I had a data in Excel data.So I have used xlsxwriter to Create graph.But I need to analyze graph.
1.Solid red line was created using xlsxwriter using excel data and was very easy to implement.
In later Enhancement,
2.In Ideal condition,The formula provided to us, we will have dotted red line. So we need to determine difference and report an error.
So First approach was, write a data in Excel sheet using formula and compare data into Excel sheet and report an error.
But we also need to represent into graph also and we will have upcoming task also in which we require graph (basically 2D and line graph) I have googled and found matplotlib which generally use for create graph. So I have very basic question,
Can anyone suggest me library which can be used for this scenario. it will be great if I have input any standard graph library(cover Line grpah) So I can put effort to familiarize with them. it will save lot of effort of us. we generally create graph for circuit analysis.
Language : Python
Environment : Linux
Library : Should be open source
I know, it is very open ended question.But I thought Let have a opinion who has used graph in Python
or is it possible to create below like diagram using matplotlib

Dyamic rendering of graph API for python

I wish to find a library which is able to render the evolution of a graph during the processing phase. Therefore you would be able to see the graph visually growing and/or pruned according to the current results processed by the classes. Is there any library for python which has the following requirements?
Assuming you are talking about a changing dataset (as opposed to the graph-theoretic type) matplotlib can do this. The documentation for the animation functionality is lengthy, but there are many examples at:
http://matplotlib.org/examples/animation/
If you are talking about the other type of a "graph", you can use networkx to manipulate and render the graph with fixed positions. Underneath it uses matplotlib as its drawing backend.

Categories