Git Product home page Git Product logo

bezier-curved-edges-networkx's People

Contributors

beyondbeneath avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

bezier-curved-edges-networkx's Issues

Error in bezier.Curve due to verify argument

Hi,

Thanks for publishing this useful code!

The issue

When I run this code, I get the following error:

Traceback (most recent call last):
  File "bezier-curved-edges-networkx/run.py", line 14, in <module>
    curves = curved_edges(G, positions)
  File "bezier-curved-edges-networkx/curved_edges.py", line 58, in curved_edges
    curveplots.append(bezier.Curve(nodes, degree=2).evaluate_multi(np.linspace(0,1,bezier_precision)).T)
  File "/lib/python3.9/site-packages/bezier/curve.py", line 101, in __init__
    self._verify_degree(verify)
  File "/lib/python3.9/site-packages/bezier/curve.py", line 161, in _verify_degree
    raise ValueError(msg)
ValueError: A degree 2 curve should have 3 nodes, not 4.

The potential fix

It looks like this is due to a release of the bezier package adding the verify argument to the Curve constructor (this release: https://bezier.readthedocs.io/en/stable/releases/0.11.0.html).

So when I set verify=False in line 58:
curveplots.append(bezier.Curve(nodes, degree=2, verify=False).evaluate_multi(np.linspace(0,1,bezier_precision)).T)
it works!

Or instead, I can change the degree:
curveplots.append(bezier.Curve(nodes, degree=3).evaluate_multi(np.linspace(0,1,bezier_precision)).T)
and this works too.

MultiDiGraph support

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?

where you get curved_edges

hi:
it is so beautiful graph via networkx.
Would you mind telling me where the "curved_edges" is from?

thank you very much!

best regards,
rawen
[email protected]

`
-- #1 Imports
import networkx as nx
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
from fa2 import ForceAtlas2

--# 1 Load the graph edges and compute the node positions using ForceAtlas2
G = nx.read_edgelist('facebook_combined.txt')
forceatlas2 = ForceAtlas2()
positions = forceatlas2.forceatlas2_networkx_layout(G, pos=None, iterations=50)

-- #1 Produce the curves
curves = curved_edges(G, positions)
lc = LineCollection(curves, color='w', alpha=0.05)

-- #1 Plot
plt.figure(figsize=(20,20))
nx.draw_networkx_nodes(G, positions, node_size=5, node_color='w', alpha=0.4)
plt.gca().add_collection(lc)
plt.tick_params(axis='both',which='both',bottom=False,left=False,labelbottom=False,labelleft=False)
plt.show()
`

Color edges by group

Hello,

First, I want to thank you for creating this and sharing it. I've been working on adding color to the graph based on spectral clustering. I mostly got the nodes to be colored by group and have been working on the edges. My plan was to create separate LineCollections per group and plot them individually with different colors. My approach was:

  1. Classify nodes into n groups
  2. Generate positions dictionary from ForceAtlas
  3. Make a new "sub network" out of each n group of nodes
  4. Make new "sub positions" dictionary from the positions dictionary for each n group
  5. Generate curves array based on the "sub network" and "sub positions"

I've been able to do this, but I'm having problems with the curved_edges function. It's this step that is causing problems:
coords = np.array([pos[x] for x in u]).reshape([edges.shape[0], 2, edges.shape[1]])
The resulting coords array just as the same x, y combo repeating over and over again. Could you tell me what this step is doing? Particularly the pos[x] part... can't figure that out.
Below is my full code, which should reproduce the issue. Thanks for your help!

import sys
import curved_edges
import networkx as nx
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
from fa2 import ForceAtlas2
from sklearn.cluster import SpectralClustering
import pandas as pd
import numpy as np

# Importing network as Pandas dataframe
network = pd.read_csv(r'/path/',sep=" ",header=None, names=['from','to'])
#network = network.rename(columns={"0":"from","1":"to"})

# Creating initial graph
G = nx.from_pandas_edgelist(network,'from','to',create_using=nx.Graph())

# Performing spectral clustering
matrix = nx.to_numpy_matrix(G)
sc = SpectralClustering(7, affinity='precomputed', n_init=100,assign_labels='discretize')
sc.fit(matrix)
clusters = pd.DataFrame({'group':sc.labels_})

# Rearraging graph for coloring
clusters = clusters.reindex(G.nodes())

# Running Force Atlas
forceatlas2 = ForceAtlas2()
positions = forceatlas2.forceatlas2_networkx_layout(G,pos=None,iterations=50)

# Making a new network based on selected cluster
network_sub = pd.merge(network,clusters[clusters['group'] ==3],left_on='to',right_index=True,how='inner').drop(['group'],axis=1).reset_index(drop=True)

# Making a list that has the nodes we want to keep
node_list = list(dict.fromkeys(network_sub['to'].tolist() + network_sub['from'].tolist()))

# Getting the subset of the Atlast positions dict
positions_sub = {k:v for k, v in positions.items() for k in node_list}

# Loading a new network based on the subset
G_sub = nx.from_pandas_edgelist(network_sub,'from','to',create_using=nx.Graph())
print(G_sub.number_of_nodes())

curves = curved_edges(G_sub,positions_sub)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.