vis.js nodes not settling in UI - vis.js

I am using vis.js to visualize my network.
The number of nodes and edges that are being passed to this library is approximately around 500 and 2000 respectively.
Earlier when my code would add nodes and edges, the browser would become unresponsive after processing 1000 edges.
I have included the following parameters in the options.
options.layout.hierarchical = true;
options.edges.smooth = false;
options.layout = {improvedLayout : false};
With options.layout = {improvedLayout : false} being added, I am able to get the output on the screen.
However the nodes are not settled and they seem to take time to adjust to the layout. Also the hierarchy is not clearly seen.
How can I correctly display all the nodes and edges in a hierarchical manner with vis.js? What are the additional parameters that I have to add?

Related

Break up graph into smallest sub-components of 2-nodes or greater

I wish to be able to separate my graph into subcomponent such that the removal of any single node would create no further sub-components (excluding single nodes). As an example see the two images below.
The first image shows the complete graph. The second image shows the sub-components of the graph when it has been split into the smallest possible subcomponents. As can be seen from the second image, the vertex names have been maintained. I don't need the new structure to be a single graph it can be a list of graphs, or even a list of the nodes in each component.
The component of nodes 4-5-6 remains as removing any of the three nodes will not create a new component as the node that was broken off will only be a single node.
At the moment I am trying to put together an iterative process, that removes nodes sequentially in ascending degree order and recurses into the resultant new components. However, it is difficult and I imagine someone else has done it better before.
You say you want the "smallest subcomponents of 2 nodes of greater", and that your example has the "smallest possible subcomponents". But what you actually meant is the largest possible subcomponents such that the removal of any single node would create no further sub-components, right? Otherwise you could just separate the graph into a collection of all of the 2-graphs.
I believe, then, that your problem can be described as finding all "biconnected components" (aka maximal biconnected subgraphs of a graph): https://en.wikipedia.org/wiki/Biconnected_component
As you said in the comments, igraph has the function biconnected_components(g), which will solve your problem. :)

Reduce openstreetmap graph size in networkx

I have a graph (transformed from OSMNX) of London's walk path, containing 667.588 edges, with different highway attributes (the street types in openstreetmap). Running a shortest_path algorithm is quite slow (4 seconds). To improve the speed, I want to largely reduce the number of edges in a systematic way without losing main connections/city structures, but not sure how to do it? Any suggestions? Is there a way to group some close nodes to a more important one, thus reduce the size?
You can extract edges with desired highway types from your main graph G:
highways_to_keep = ['motorway', 'trunk', 'primary']
H = nx.MultiDiGraph()
for u,v,attr in G.edges(data=True):
if attr['highway'] in highways_to_keep:
H.add_edge(u,v,attr_dict=attr)
H.node[u] = G.node[u]
H.node[v] = G.node[v]
Here, we first initialized an empty MultiDiGraph, which is a type of graph used by OSMnx, then populate it with data from the main graph G, if the 'highway' attribute is in our list of highways_to_keep. You can find more about highway types in this OpenStreetMap page.
Our graph is a valid NetworkX graph, but you need to do one more thing before you can take advantage of OSMnx functionalities as well. if you execute G.graph, you will see graph attributes which contains crs (coordinate reference system) and some other things. you should add this information into your newly create graph:
H.graph = G.graph
here is the plot of H , osmnx.plot_graph(H):
It depends what type of network you're working with (e.g., walk, bike, drive, drive_service, all, etc.). The drive network type would be the smallest and prioritize major routes, but at the expense of pedestrian paths and passageways.
OSMnx also provides the ability to simplify the graph's topology with a built-in function. This is worth doing if you haven't already as it can reduce graph size by 90% sometimes while correctly retaining all intersection and dead-end nodes, as well as edge geometries, faithfully.
The above solution does not work anymore since the networkx library has changed. Specifically
H.node[u] = G.node[u]
is not supported anymore.
The following solution relies on the osmnx.geo_utils.induce_subgraph and used a node list as an argument to this function.
highways_to_keep = ['motorway', 'trunk', 'primary', 'secondary', 'tertiary']
H = nx.MultiDiGraph() # new graph
Hlist = [] # node list
for u,v,attr in G.edges(data=True):
if "highway" in attr.keys():
if attr['highway'] in highways_to_keep :
Hlist.append(G.nodes[u]['osmid'])
H = ox.geo_utils.induce_subgraph(G, Hlist)
The osmnx simplification module worked for me in this case https://osmnx.readthedocs.io/en/stable/osmnx.html#module-osmnx.simplification:
osmnx.simplification module
Simplify, correct, and consolidate network topology.
osmnx.simplification.consolidate_intersections(G, tolerance=10, rebuild_graph=True, dead_ends=False, reconnect_edges=True)
Consolidate intersections comprising clusters of nearby nodes.
osmnx.simplification.simplify_graph(G, strict=True, remove_rings=True)
Simplify a graph’s topology by removing interstitial nodes.

Super position of small network over big network

I am working on PPI network and for the network plot I am using Gephi and rgexf package. In my network there are 9453 no. of vertices and 36888 connections. So, when plot the network on gephi we can't analyse anything, so I plot only top 50 nodes network. Now I want to highlight that 50 node's network over the top 100 nodes network. Here the top means the nodes which has highest degree. So is there any way to do it?
This the plot for top 50 nodes, there is one node which is not connected to any of the node in top50:
I am struggling from few days.
UPDATE - I updated the descriptions
Ok so this is not totally trivial but not straightforward either. I have created a random network with 500 nodes to show you an example.
After you load your network with Gephi you need at least to run the Average degree from the statistics.
You then go to the Filters section, select Attributes>Range>In-degree, double-click and press the Filter button (Note: In your case you should just see Degree but the rest still apply)
Move the slider to the right so that in the Context panel the number of remaining nodes reaches ~50
Here is how it looks for me
COLORING:
While you keep the Filter button pressed you can apply a different color to the filtered nodes. In my case I went in Ranking>Nodes selected InDegree and applied a green color. Note that you can also select Degree to get the effect you want. The respective panel looks like that:
This colors only the filtered nodes. Alternatively, you can apply the node brush but then it becomes a bit dull :). There is a 3rd option but I leave it as an exercise :).
The final graph looks like that for me.
Programmatically you could do something similar in igraph. You can select the nodes with top-50 indegrees, assign them a color, assign all the rest a different color and export to GraphML.
I hope it helped.
What you can do is importing the network to gephi ASIS and compute degree centrality, this will generate a variable with the degree of each vertex in the graph. After that you can use the filter tool (as illustrated in this presentation http://www.clementlevallois.net/gephi/tuto/en/gephi_advanced%20functions_en.pdf) to restrict the number of vertices to work with using the degree variable. That's the easy way.
Alternatively, you can calculate each node's degree using either igraph or sna packages, and include such as an attribute of your network in the write.gexf function.

Add nodes to a fixed backbone when drawing a networkx graph with graphviz, some of the larger nodes are ending up crammed together

I have created a graph using networkx. I am drawing the graph using graphviz, specifically with these lines of code:
pos = nx.graphviz_layout(G2, prog='neato', args='-Goverlap=prism')
plt.figure(figsize=(10, 14))
nx.draw(G2, pos, node_size=sizes, alpha=1, nodelist=nodes, node_color=colors, with_labels=True, labels=labelDict, font_size=8)
The graph consists of a "backbone" of a few larger nodes, to which are attached a few hundred smaller nodes.
I have used args='-Goverlap=prism' (in the first line of code above) to space out the graph, but this has created a problem. It matters much more that the larger nodes be spaced out, but, because of how many small nodes there are, some of the larger nodes are ending up crammed together.
My thoughts on a solution are to generate a graph with only the larger nodes to ensure that they are properly spaced, then add the smaller nodes to this graph without changing the layout of the original nodes. I have done some research, and it seems to be somewhat tricky to add new nodes without changing old ones in graphviz. It is possible to "pin" nodes, but I am unsure of how to do this within networkx.
This is what the graph currently looks like:
Your thoughts seem reasonable. The following code generates a graph, assigns an initial position to nodes 1 and 2, then uses nx.spring_layout to assign positions to all of them. I allow for node 2 to move, but node 1 stays fixed.
import networkx as nx
G=nx.path_graph(6)
originalpos = {1:(0,0), 2:(1,0)}
newpos = nx.spring_layout(G, pos=originalpos, fixed=[1])
newpos
> {0: array([-0.39442754, -0.35733777]),
1: array([ 0., 0.]),
2: array([ 0.44050048, 0.3734393 ]),
3: array([ 0.8658906 , 0.80306291]),
4: array([ 1.21367619, 1.27878715]),
5: array([ 1.45676553, 1.72154196])}
For your case you would get the positions for your backbone and then use those nodes as your fixed list.

How can I make DOT/neato graphs more compact without introducing overlap?

My question is essentially the same as this one but the given answer doesn't work for me.
Here is a sample rendering (source) with
compound=true;
overlap=scalexy;
splines=true;
layout=neato;
There is some unnecessary overlap in the edges but this isn't too bad, the main problem is all the wasted space.
I tried setting sep=-0.7; and here's what happens.
The spacing is much better but now there is some overlap with the nodes. I experimented with different overlap parameters and this is the only one which gives remotely acceptable results.
I tried changing to fdp layout and setting the spring constant attribute K globally but I just got stuff like this:
The source is all straightforward a--b--c sort of stuff, no fancy tricks.
What I want is for all edges to be shortened as much as possible (up to a minimum) provided that this adjustment doesn't introduce any new overlaps, which is where sep fails completely. That doesn't seem like it should be too hard for a layout engine to do. Is it possible with the graphviz suite? I don't mind changing rendering software, but I don't want to annotate the source on a per-node or per-edge basis.
My ideal result would be to minimize the deviation in edge length, considered one node at a time, i.e. each node would have edges of equal length apart from the necessary exceptions, but that's wishful thinking. The priority is to reduce the length of each edge with the constraint that this cannot introduce overlap.
I will accept partial solutions but they must be fully automatic and open source.
How can I do this? Thanks.
I found https://sites.google.com/site/kuabus/programming-by-hu/graphviz-test-tool, an interactive tool for parameterizing the many options and repeatedly rendering them. I went through the full list provided by the Java application, eventually ending up with this set of attributes:
overlap=false
maxiter=99999999
damping=9999999
voro_margin=.001
start=0.1
K=1
nodesep=999999999999
labelloc=c
defaultdist=9999999
size=20,20
sep=+1
normalize=99999999
labeljust=l
outputorder=nodesfirst
concentrate=true
mindist=2
fontsize=99999999
center=true
scale=.01
inputscale=99999999
levelsgap=9999999
epsilon=0.0001
I was not able to find a parameterization of neato that made producing the desired "moderately scaled" graph possible.
You should set
overlap = compress;
this should compress it at much as possible.
Try sep = +1; first, and then play with values between 0 and +1 to find the optimal setting for you.
I have a graph with 50 nodes and 68 edged (sorry cannot publish the whole picture, just a fragment). Found two reasonable presets (1 and 2):
digraph {
graph[
# 1. Less overlaps but less compact.
# This is the choice for now.
layout=neato; overlap=prism; overlap_scaling=-3.5;
# 2. More compact but some overlaps exist (may be adjusted by `sep`).
#layout=neato; overlap=voronoi; sep=-0.15;
# The following is common.
outputorder=nodesfirst, # Will always draw edges over nodes.
splines=curved;
]
node[fontname="Helvetica",];
node[shape=box;style="filled";penwidth="0.5";width=0;height=0;margin="0.05,0.05"];
edge[label=" ";color="#000080";penwidth="0.5";arrowhead="open";arrowsize="0.7";];
. . .
}

Resources