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)
Related
I'm trying to visualize markov style state diagrams.
I've tried using pygraphviz via both direct dot language and networkx.
I've tried using pyplot within matplotlib.
In both cases the outcome is ugly. In pyplot the arrows are just thicker lines, and in pygraphviz the labeled lines aren't arranged well.
Personally I prefer the networkx->pygraphviz option. Here's a brief code snippet that illustrates my question.
G = nx.DiGraph()
G.add_edge(0,1,weight=0.5)
G.add_edge(1,2,weight=0.5)
G.add_edge(2,3,weight=0.5)
G.add_edge(3,4,weight=0.5)
G.add_edge(1,0,weight=0.5)
G.add_edge(2,1,weight=0.5)
G.add_edge(3,2,weight=0.5)
G.add_edge(4,3,weight=0.5)
for u,v,d in G.edges(data=True):
d['label'] = d.get('weight','')
A = nx.drawing.nx_agraph.to_agraph(G)
A.layout(prog='dot')
A.draw('test.png')
Which produces
ugly graph labels
In reality I want something like this
better graph
Or even better yet something like this pretty transition diagram.
I would have embedded the photos, but I'm not yet allowed. :(
Thanks!
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.
I am trying to visualize a Control Flow Graph in Python using pyqtgraph. I have the following two problems.
How can I visualize the edges with a direction?
How can I visualize a self edge?
I tried looking into the documentation, but couldn't find. Obviously, I didn't get time to read it all!
While pyqtgraph is awesome, for my use case I found a much better tool to do this.
graphviz is a nice tool to develop Control Flow Graphs quite conveniently, and has a large number of features for this particular problem.
For direction, you might add a pg.ArrowItem at the end of each line (although this could have poor performance for large networks), and for self connections, QtGui.QGraphicsEllipseItem combined with an arrow.
I am trying to find an easy way to animate at tree where nodes are circles with text in them and edges are lines.
Once in a while an event occurs that changes the status of one of the nodes, and this should change the color of the node.
I have looked at networkx as in Animating Network Growth with NetworkX and Matplotlib but I am unsure if you can get a correct tree layout here, and that the animation is performant.
I do not have a lot of time so I would greatly appreciate suggestions for easy (hacky) ways of doing this.
The the best thing would be to have a function to call:
change_color(node)
that would update a Qt4 gui or something similar. It would be really good if I can use a graph/tree library so that I only have to specify the tree in a simple format and the library takes care of positioning nodes in the gui.
I already have a way of clustering my graph, so the process of clustering isn't the issue here. What I want to do is, once we have all the nodes clustered - to draw the clustered graph in Python, something like this:
I looked into networkx, igraph and graph-tool, but they seem to do the clustering, but not the drawing. Any ideas and propositions of what library should I use for drawing the already clustered graph, which will minimize the number of crossing links?
Take a look at GraphViz
http://www.graphviz.org/Gallery/directed/cluster.html
There's a Python binding for that, but I have to say I always create the text files directly as they're easy enough to write. Don't be fooled by the plain-looking examples, every aspect of your graph is highly customizable and you can make some pretty nifty graph visualizations with it. Not sure about nested clusters though, never tried that out.