Skip to main content

Python package to create interactive network based on d3js.

Project description

Interactive force-directed network creator (d3graph)

Python PyPI Version License Coffee Github Forks GitHub Open Issues Project Status Downloads Downloads

Star it if you like it!
  • d3graph is a python package that simplifies the task of creating interactive and stand-alone networks in d3 javascript using python. For this package I was inspired by d3 javascript examples but there was no python package that could create such interactive networks. Therefore I decided to create a package that automatically creates d3js javascript and html code based on a input adjacency matrix in python! This library does not require you any additional installation, downloads or setting paths to your systems environments. You just need python and this library. All other is taken care off. Huray!

This package provides functionality to create a interactive and stand-alone network that is build on d3 javascript. D3graph only requirs an adjacency matrix in the form of an pandas dataframe. Each column and index name represents a node whereas values >0 in the matrix represents an edge. Node links are build from rows to columns. Building the edges from row to columns only matters in directed cases. The network nodes and edges can be adjusted in weight, color etc, based on user defined paramters.

Contents

Installation

d3graph is compatible with Python 3.6+ and runs on Linux, MacOS X and Windows. Note: d3graph requires networkx to be v2 or higher. It is distributed under the Apache 2.0 license. There are two ways to install d3graph:

  • Install d3graph from PyPI (recommended):
pip install d3graph
  • Install d3graph from the GitHub source:
git clone https://github.com/erdogant/d3graph.git
cd d3graph
pip install "networkx>=2"
python setup.py install

Quick Start

In order to create an interactive and stand-alone d3graph, following workflow can be used:

  • Import d3graph method
from d3graph import d3graph
  • Create simple example dataset for which the input matrix should look this:
+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
|    |   0 |   1 |   2 |   3 |   4 |   5 |   6 |   7 |   8 |   9 |   10 |   11 |   12 |   13 |   14 |   15 |   16 |   17 |   18 |   19 |   20 |   21 |   22 |   23 |   24 |   25 |   26 |   27 |   28 |   29 |   30 |   31 |   32 |   33 |
+====+=====+=====+=====+=====+=====+=====+=====+=====+=====+=====+======+======+======+======+======+======+======+======+======+======+======+======+======+======+======+======+======+======+======+======+======+======+======+======+
|  0 |   0 |   1 |   1 |   1 |   1 |   1 |   1 |   1 |   1 |   0 |    1 |    1 |    1 |    1 |    0 |    0 |    0 |    1 |    0 |    1 |    0 |    1 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    1 |    0 |    0 |
+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
|  1 |   1 |   0 |   1 |   1 |   0 |   0 |   0 |   1 |   0 |   0 |    0 |    0 |    0 |    1 |    0 |    0 |    0 |    1 |    0 |    1 |    0 |    1 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    1 |    0 |    0 |    0 |
+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
...
+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
| 32 |   1 |   1 |   1 |   0 |   5 |   0 |   0 |   1 |   0 |   0 |    0 |    0 |    1 |    1 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |
+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
| 33 |   1 |   0 |   0 |   0 |   0 |   6 |   1 |   0 |   0 |   0 |    1 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |
+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
G = nx.karate_club_graph()
adjmat = nx.adjacency_matrix(G).todense()
adjmat = pd.DataFrame(index=range(0,adjmat.shape[0]), data=adjmat, columns=range(0,adjmat.shape[0]))
adjmat.iloc[3,4]=5
adjmat.iloc[4,5]=6
  • Make d3graph
G_d3   = d3graph(adjmat)

The output looks as below:

source = ['node A','node F','node B','node B','node B','node A','node C','node Z']
target = ['node F','node B','node J','node F','node F','node M','node M','node A']
weight = [5.56, 0.5, 0.64, 0.23, 0.9,3.28,0.5,0.45]

# Import library
from d3graph import d3graph, vec2adjmat

# Convert to adjacency matrix
adjmat = vec2adjmat(source, target, weight=weight)

print(adjmat)
# target  node A  node B  node F  node J  node M  node C  node Z
# source                                                        
# node A    0.00     0.0    5.56    0.00    3.28     0.0     0.0
# node B    0.00     0.0    1.13    0.64    0.00     0.0     0.0
# node F    0.00     0.5    0.00    0.00    0.00     0.0     0.0
# node J    0.00     0.0    0.00    0.00    0.00     0.0     0.0
# node M    0.00     0.0    0.00    0.00    0.00     0.0     0.0
# node C    0.00     0.0    0.00    0.00    0.50     0.0     0.0
# node Z    0.45     0.0    0.00    0.00    0.00     0.0     0.0

# Example A: simple interactive network
out = d3graph(adjmat)

# Example B: Color nodes
out = d3graph(adjmat, node_color=adjmat.columns.values)

# Example C: include node size
node_size = [10,20,10,10,15,10,5]
out = d3graph(adjmat, node_color=adjmat.columns.values, node_size=node_size)

# Example D: include node-edge-size
out = d3graph(adjmat, node_color=adjmat.columns.values, node_size=node_size, node_size_edge=node_size[::-1], cmap='Set2')

# Example E: include node-edge color
out = d3graph(adjmat, node_color=adjmat.columns.values, node_size=node_size, node_size_edge=node_size[::-1], node_color_edge='#00FFFF')

# Example F: Change colormap
out = d3graph(adjmat, node_color=adjmat.columns.values, node_size=node_size, node_size_edge=node_size[::-1], node_color_edge='#00FFFF', cmap='Set2')

# Example H: Include directed links. Arrows are set from source -> target
out = d3graph(adjmat, node_color=adjmat.columns.values, node_size=node_size, node_size_edge=node_size[::-1], node_color_edge='#00FFFF', cmap='Set2', directed=True)

Example: including Dataframe with additional node information

G = nx.karate_club_graph()
adjmat = nx.adjacency_matrix(G).todense()
adjmat=pd.DataFrame(index=range(0,adjmat.shape[0]), data=adjmat, columns=range(0,adjmat.shape[0]))
adjmat.columns=adjmat.columns.astype(str)
adjmat.index=adjmat.index.astype(str)

# Make the dataframe
df = pd.DataFrame(index=adjmat.index)

# Add some columns. Note that columns that start with: node_ are removed from the information.

df['degree']=np.array([*G.degree()])[:,1]
df['other info']=np.array([*G.degree()])[:,1]

node_color = []
for i in range(0,len(G.nodes)):
    node_color.append(G.nodes[i]['club'])
    node_name=node_color
df['name']=node_name

node_size = df.degree.values*2

# Make some graphs
out = d3graph(adjmat, df=df, node_color=node_size, node_size=node_size)

Contribute

  • Thanks to Oliver Verver who helped to fix some bugs in d3js (https://github.com/oliver3).
  • All kinds of contributions are welcome!

Citation

Please cite d3graph in your publications if this is useful for your research. Here is an example BibTeX entry:

@misc{erdogant2019d3graph,
  title={d3graph},
  author={Erdogan Taskesen},
  year={2019},
  howpublished={\url{https://github.com/erdogant/d3graph}},
}

Maintainer

  • Erdogan Taskesen, github: erdogant
  • Contributions are welcome.
  • If you wish to buy me a Coffee for this work, it is very appreciated :)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

d3graph-0.1.11.tar.gz (93.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

d3graph-0.1.11-py3-none-any.whl (97.3 kB view details)

Uploaded Python 3

File details

Details for the file d3graph-0.1.11.tar.gz.

File metadata

  • Download URL: d3graph-0.1.11.tar.gz
  • Upload date:
  • Size: 93.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.7.0 requests/2.23.0 setuptools/46.4.0.post20200518 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.3

File hashes

Hashes for d3graph-0.1.11.tar.gz
Algorithm Hash digest
SHA256 0f9ad92e73e257811ab5b3c1e63b862abf9a0c6181cad71443e265ae50bfddcf
MD5 d8745bf4d1dc7b546179e66cce3d18ff
BLAKE2b-256 eb28e9e83410f8fb28ab5f5f94e3e5c4cb1fbcbda7506c16b398f9d10ca22e91

See more details on using hashes here.

File details

Details for the file d3graph-0.1.11-py3-none-any.whl.

File metadata

  • Download URL: d3graph-0.1.11-py3-none-any.whl
  • Upload date:
  • Size: 97.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.7.0 requests/2.23.0 setuptools/46.4.0.post20200518 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.3

File hashes

Hashes for d3graph-0.1.11-py3-none-any.whl
Algorithm Hash digest
SHA256 a47c88a46726c2bd06901f69304297979e97cd16c613def1aee038e1ff9e8252
MD5 7068dc57d3d9360b935f14a7439bfe8d
BLAKE2b-256 e51e5da4f099229e1a850d842e3bd8339ea99bcfe78a5dacbaea8875adc3d6a5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page