beyondbeneath / bezier-curved-edges-networkx

Function to produce Bezier curves for the edges in a NetworkX graph
MIT License
61 stars 12 forks source link

MultiDiGraph support #4

Open Jeddu opened 4 years ago

Jeddu commented 4 years ago

Hi, I'm using your curved_edges.py, it is very useful.

I've found a problem when I tried to use it with a MultiGraph or MultiDiGraph. This is what I found and what I changed to get it work.

If you are using G as MultiDiGraph, edges = np.array(G.edges()) causes this problem:

in curved_edges(G, pos, dist_ratio, bezier_precision, polarity)
      6     # Get nodes into np array
      7     edges = np.array(G.edges())
----> 8     l = edges.shape[0]
      9 
     10     if polarity == 'random':

IndexError: tuple index out of range

I changed it to support MultiDiGraph edges: (a, b, c) edges = np.array([edge for edge in G.edges()])

The next issue is to not use a fixed degree=2, In my use case, I notice the degree can change so I found a better option in bezier.Curve.from_nodes(nodes). Since it just return the Curve computing the degree itself.

So, if I run: curveplots.append(bezier.Curve(nodes, degree=2).evaluate_multi(np.linspace(0,1,bezier_precision)).T)

I get this:

<ipython-input-10-53b971525f16> in curved_edges(G, pos, dist_ratio, bezier_precision, polarity)
     56     for i in range(l):
     57         nodes = node_matrix[:,i,:].T
---> 58         curveplots.append(bezier.Curve(nodes, degree=2).evaluate_multi(np.linspace(0,1,bezier_precision)).T)
     59 
     60     # Return an array of these curves

~/py3.6/lib/python3.6/site-packages/bezier/curve.py in __init__(self, nodes, degree, copy, verify)
    102         super(Curve, self).__init__(nodes, copy=copy)
    103         self._degree = degree
--> 104         self._verify_degree(verify)
    105 
    106     @classmethod

~/py3.6/lib/python3.6/site-packages/bezier/curve.py in _verify_degree(self, verify)
    162             f"{expected_nodes} nodes, not {num_nodes}."
    163         )
--> 164         raise ValueError(msg)
    165 
    166     @property

ValueError: A degree 2 curve should have 3 nodes, not 4.

So I changed it to: curveplots.append(bezier.Curve.from_nodes(nodes).evaluate_multi(np.linspace(0,1,bezier_precision)).T)

Lastly, would you consider to publish your module in pypi?

beyondbeneath commented 4 years ago

Thanks for your comments. I hadn't had any experience with a MultiDiGraph so glad you could adapt it to your needs and are finding it useful!

I haven't really considered taking this seriously - initially I was going to try and merge this capability into NetworkX natively, but didn't find the time. Would be happy to support if this if it's something you are keen to take on.