0

I am trying to create bipartite of certain nodes, for small numbers it looks perfectly fine:

Image for around 30 nodes

Unfortunately, this isn't the case for more nodes like this one:

Image for more nodes

My code for determining the position of each node looks something like this:

pos = {}
pos[SOURCE_STRING] = (0, width/2)
row = 0
for arr in left_side.keys():
    pos[str(arr).replace(" ","")]=(NODE_SIZE, row)
    row += NODE_SIZE
row = 0
for arr in right_side.keys():
    pos[str(arr).replace(" ","")]=(2*NODE_SIZE,row)
    row += NODE_SIZE
pos[SINK_STRING] = (3*NODE_SIZE, width/2)
return pos

And then I feed it to the DiGraph class:

G = nx.DiGraph()
G.add_nodes_from(nodes)
G.add_edges_from(edges, len=1)
nx.draw(G, pos=pos ,node_shape = "s", with_labels = True,node_size=NODE_SIZE)

This doesn't make much sense since they should be in the same distance from each other since NODE_SIZE is constant it doesn't change for the rest of the program.

Following this thread:

Bipartite graph in NetworkX

Didn't help me either.

Can something be done about this?

Edit(Following Paul Brodersen Advice using netGraph:

Used this documentation: netgraph doc

And still got somewhat same results, such as: netgraph try

Using edges and different positions, also played with node size, with no success.

Code:

netgraph.Graph(edges, node_layout='bipartite', node_labels=True)
plt.show()
linuxbeginner
  • 39
  • 1
  • 7
  • In networkx, the node size is specified in display coordinates, not data coordinates. You can convince yourself that this is true by zooming into a networkx plot. The apparent size of the nodes does not change, even though the zoom window has much narrower data coordinates than the original view. This behaviour makes precomputing a layout in the manner that you are attempting very challenging. Yes, your nodes are spaced in the same manner. However, the ratio of data coordinates to display coordinates now has also changed, such that each node has much larger size in data coordinates now. – Paul Brodersen Sep 26 '22 at 11:14
  • You have two options: 1) You can compute a layout as before (in data coordinates) and then convert your node size to display coordinates using [transforms](https://matplotlib.org/stable/tutorials/advanced/transforms_tutorial.html). If you don't resize the window, or zoom in, or do anything else that changes the ratio from display to data coordinates then this is a viable option. – Paul Brodersen Sep 26 '22 at 11:22
  • 2) You can use [netgraph](https://github.com/paulbrodersen/netgraph), which is a network visualisation library that I wrote chiefly because the different coordinate systems in networkx were making my life exceedingly difficult. In netgraph, everything is specified in data coordinates (with a constant scalar of 1/100 for node sizes and edge widths). There are some examples for bipartite network visualisations [here](https://netgraph.readthedocs.io/en/latest/sphinx_gallery_output/plot_14_bipartite_layout.html#sphx-glr-sphinx-gallery-output-plot-14-bipartite-layout-py). – Paul Brodersen Sep 26 '22 at 11:27
  • I really don't get what you mean. I used the documentation: netgraph.readthedocs.io/en/latest/graph_classes.html `netgraph.Graph(edges, node_layout='bipartite', node_labels=True) plt.show() ` And still, it looks pretty much the same, I used different size nodes and different positions: [second try][1] – linuxbeginner Sep 27 '22 at 14:16
  • I was trying to explain why your sentence "they should be in the same distance from each other since NODE_SIZE is constant" is incorrect. In that statement, you are assuming that the NODE_SIZE is in data units (which would result in the same apparent spacing for 30 nodes and for many more nodes), when it is, in fact, in display units resulting in a change in the apparent spacing. If you repeat the experiment in `netgraph` (30 nodes vs. many nodes), you will notice that the apparent spacing between nodes remains constant. – Paul Brodersen Sep 27 '22 at 14:22
  • For understanding the difference between display units and data units, I highly recommend reading the transfom tutorial I linked above. – Paul Brodersen Sep 27 '22 at 14:23
  • Ok, so if I understood correctly, I need to change the size_node and the space between each node according to the number of nodes that are in the graph right? Because they do not scale the same. I changed the node size and the distances between them and still got no good-for-view results – linuxbeginner Sep 27 '22 at 15:07

1 Answers1

0

In your netgraph call, you are not changing the node size. My suggestion with 30 nodes:

enter image description here

import numpy as np
import matplotlib.pyplot as plt

from netgraph import Graph

edges = np.vstack([np.random.randint(0, 15, 60),
                   np.random.randint(16, 30, 60)]).T

Graph(edges, node_layout='bipartite', node_size=0.5, node_labels=True, node_label_offset=0.1, edge_width=0.1)
plt.show()

With 100 nodes:

enter image description here

import numpy as np
import matplotlib.pyplot as plt

from netgraph import Graph

edges = np.vstack([np.random.randint(0, 50, 200),
                   np.random.randint(51, 100, 200)]).T

Graph(edges, node_layout='bipartite', node_size=0.5, node_labels=True, node_label_offset=0.1, edge_width=0.1)
plt.show()
Paul Brodersen
  • 11,221
  • 21
  • 38