Git Product home page Git Product logo

bezier-curved-edges-networkx's Introduction

Curved Bezier edges in NetworkX

NB: code was originally written in July 2017, and first published here in April 2019.

This function (curved_edges in curved_edges.py) creates some curved Bezier edges for a NetworkX graph. The original motivation was to mimic the types of edge curves found in Gephi when I was producing an animation showing the ForceAtlas2 algorithm converging. While it now appears NetworkX offers some kind of curved edges (though only for directed graphs, via the connectionstyle property of FancyArrowPatch) this is substantially faster and more versatile.

This defaults to using Gephi's Bezier curve defintion, in which you travel 0.2 distance units (of the length of the line connecting the two nodes) from each node toward each other (magenta markers); then travel that same distance again but perpendicular to the connecting line (the red 'control points'). The nodes along with these control points, now define the curve by four (x,y) coordinates.

Dependencies

Sample usage

Facebook

The Stanford SNAP project hosts many network datasets, one of which is the Facebook social network from 10 individuals.

# Imports
import networkx as nx
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
from fa2 import ForceAtlas2
from curved_edges import curved_edges

# 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)

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

# 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()

Game of Thrones

This repository hosts character interaction data for Game of Thrones, with one edge file per season. We can combine all the files and plot the results, and note we can modify the width (as Gephi does) according to the weight of the edges too:

# Imports
import networkx as nx
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
from fa2 import ForceAtlas2
from curved_edges import curved_edges

# Concatenate seasons 1-7
got_data = 'got-s{}-edges.csv'
dfg = pd.DataFrame()
for i in range(7):
	df_current = pd.read_csv(got_data.format(i+1),
                           names=['source','target','weight','season'],
                           skiprows=1)
	dfg = pd.concat([dfg, df_current])
dfg.drop(['season'], axis=1, inplace=True)

# Group by the edges so they are not duplicated
dfgt = dfg.groupby(['source','target'], as_index=False).agg({'weight':'sum'})

# Remove some outliers
outliers = ['BLACK_JACK','KEGS','MULLY']
dfgt = dfgt[~dfgt.source.isin(outliers)&~dfgt.target.isin(outliers)]

# Load graph from pandas and calculate positions
G = nx.from_pandas_edgelist(dfgt, source='source', target='target', edge_attr='weight')
forceatlas2 = ForceAtlas2(edgeWeightInfluence=0)
positions = forceatlas2.forceatlas2_networkx_layout(G, pos=None, iterations=1000)

# Get curves
curves = curved_edges(G, positions)

# Make a matplotlib LineCollection - styled as you wish
weights = np.array([x[2]['weight'] for x in G.edges(data=True)])
widths = 0.5 * np.log(weights)
lc = LineCollection(curves, color='w', alpha=0.25, linewidths=widths)

# Plot
plt.figure(figsize=(10,10))
plt.gca().set_facecolor('k')
nx.draw_networkx_nodes(G, positions, node_size=10, node_color='w', alpha=0.5)
plt.gca().add_collection(lc)
plt.tick_params(axis='both',which='both',bottom=False,left=False,labelbottom=False,labelleft=False)
plt.show()

bezier-curved-edges-networkx's People

Contributors

beyondbeneath avatar

Watchers

 avatar

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.