-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
312 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,63 @@ | ||
About this project | ||
================== | ||
|
||
Netwulf is an interactive visualization engine for ``networkx`` Graph-objects. | ||
Netwulf is an interactive visualization engine for networkx_ Graph-objects. | ||
Unlike other visualization methods, it is neither slow, nor does it rely | ||
to install any crude dependencies. On top, fine-tuning visualizations | ||
is made simple due to the interactive visualization nature and reproducing visualizations | ||
is made possible thanks to seamless communication between Python and the | ||
visualization tool. | ||
|
||
Quick example | ||
------------- | ||
|
||
.. code:: python | ||
import networkx as nx | ||
from netwulf import visualize | ||
G = nx.barabasi_albert_graph(100,2) | ||
visualize(G) | ||
.. figure:: img/BA.png | ||
|
||
started visualization | ||
|
||
Why should I use netwulf | ||
------------------------ | ||
|
||
Pros | ||
~~~~ | ||
|
||
- interactive | ||
- interactive styling of network visualizations in the browser, started from Python | ||
- no compiling needed | ||
- no external program needed | ||
- cross-platform | ||
- seamlessly use the inferred style back in Python | ||
- redraw the visualization in Python using matplotlib | ||
|
||
Cons | ||
~~~~ | ||
|
||
- no multiedges yet | ||
- no multiedges yet | ||
- no rendering of directed edges | ||
|
||
|
||
Install | ||
------- | ||
|
||
:: | ||
|
||
$ pip install netwulf | ||
pip install netwulf | ||
|
||
|
||
Bug reports & contributing | ||
-------------------------- | ||
|
||
You can contribute to the `public repository`_ and raise issues there. | ||
|
||
|
||
.. _`public repository`: https://github.com/benmaier/netwulf | ||
.. _networkx: https://networkx.github.io/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
Visualize Groups | ||
---------------- | ||
|
||
Cluster a network and visualize it with groups. | ||
|
||
.. code:: python | ||
import networkx as nx | ||
import community | ||
import netwulf as wulf | ||
G = nx.random_partition_graph([10,10,10],.25,.01) | ||
bb = community.best_partition(G) # dict of node-community pairs | ||
nx.set_node_attributes(G, bb, 'group') | ||
wulf.visualize(G) | ||
.. figure:: img/random_partition_graph.png | ||
|
||
colored partition |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file was deleted.
Oops, something went wrong.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
Reproducing the figure in Python | ||
-------------------------------- | ||
|
||
Once retrieved, the stylized network data can be used | ||
to reproduce the figure in Python. To this end you can use | ||
the function :mod:`netwulf.tools.draw_netwulf`. | ||
|
||
.. code:: python | ||
import networkx as nx | ||
import netwulf as wulf | ||
G = nx.barabasi_albert_graph(100,1) | ||
stylized_network, config = wulf.visualize(G) | ||
import matplotlib.pyplot as pl | ||
fig, ax = wulf.draw_netwulf(G) | ||
pl.show() | ||
A visualization window is opened and the network can be stylized. | ||
Once you're done, press the button `Post to Python`. Afterwards, | ||
the figure will be redrawn in matplotlib and opened. | ||
|
||
.. figure:: img/reproduced_figure.png | ||
|
||
Reproduced figure | ||
|
||
In order to add labels, use ``matplotlib``'s text function. | ||
Node positions and labels are saved in the stylized network, so | ||
for the first node this might look like | ||
|
||
.. code:: python | ||
ax.text( | ||
network_properties['nodes'][0]['pos'][0], | ||
network_properties['nodes'][0]['pos'][1], | ||
network_properties['nodes'][0]['id'] | ||
) |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
Network manipulation | ||
-------------------- | ||
|
||
Filtering | ||
~~~~~~~~~ | ||
|
||
Sometimes you have multiple edge or node attributes which can be | ||
used to style your network. Using :mod:`netwulf.tools.get_filtered_network` | ||
you can get a filtered network, where ``edge_weight_key`` is the name | ||
of the edge attribute which will be used as the weight in the visualization | ||
and ``node_group_key`` is the node attributed following which the nodes | ||
will be grouped and colored in the visualization. Here's an example | ||
|
||
.. code:: python | ||
import networkx as nx | ||
import netwulf as wulf | ||
import numpy as np | ||
G = nx.barabasi_albert_graph(100,1) | ||
for u, v in G.edges(): | ||
# assign two random edge values to the network | ||
G[u][v]['foo'] = np.random.rand() | ||
G[u][v]['bar'] = np.random.rand() | ||
# assign node attributes according to some generic grouping | ||
grp = {u: 'ABCDE'[u%5] for u in G.nodes() } | ||
nx.set_node_attributes(G, grp, 'wum') | ||
# filter the Graph to visualize one where the weight is determined by 'foo' | ||
new_G = get_filtered_network(G,edge_weight_key='foo') | ||
visualize(new_G) | ||
# filter the Graph to visualize one where the weight is determined by 'bar' | ||
# and the node group (coloring) is determined by the node attribute 'wum' | ||
new_G = get_filtered_network(G,edge_weight_key='bar',node_group_key='wum') | ||
visualize(new_G) | ||
Binding positions | ||
~~~~~~~~~~~~~~~~~ | ||
|
||
If the network has node attributes ``'x'`` and ``'y'``, those will be used as default | ||
values in the visualization. In order to reproduce a visualization or continue | ||
where you left off last time, you can bind the positions to the network | ||
|
||
.. code:: python | ||
wulf.bind_positions_to_network(G, stylized_network) | ||
There's no return value and the positions are directly written to the Graph-object ``G``. | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
Use network style in Python | ||
--------------------------- | ||
|
||
The network data tuned by the visualization can be posted back | ||
to Python. The visualization function can actually return | ||
two dictionaries, the first containing information about the stylized | ||
network, the second containing information about the | ||
visualization control configuration. | ||
|
||
Start a visualization like this | ||
|
||
.. code:: python | ||
import networkx as nx | ||
import netwulf as wulf | ||
G = nx.barabasi_albert_graph(100,2) | ||
stylized_network, config = wulf.visualize(G) | ||
A visualization window is opened and the network can be stylized. | ||
Once you're done, press the button `Post to Python`. | ||
|
||
.. figure:: img/post_to_python.png | ||
|
||
Post to Python | ||
|
||
Pressing this button will lead the data to be posted back to Python. | ||
Subsequently the browser window will be closed. The Python kernel will | ||
not be responding until either the `Post to Python`-button is pressed | ||
or the ``KeyboardInterrupt`` signal is send (manually or using the `Stop`-Button | ||
in a Jupyter notebook). | ||
|
||
The returned stylized network dictionary will contain all the necessary information | ||
to reproduce the figure. It will look something like this. | ||
|
||
.. code:: python | ||
stylized_network = { | ||
'xlim': [0, 833], | ||
'ylim': [0, 833], | ||
'linkColor': '#7c7c7c', | ||
'linkAlpha': 0.5, | ||
'nodeStrokeColor': '#000000', | ||
'nodeStrokeWidth': 0.75, | ||
'links': [{'link': [0, 2], 'width': 3}, | ||
{'link': [0, 3], 'width': 3}, | ||
{'link': [0, 4], 'width': 3}, | ||
{'link': [1, 2], 'width': 3}, | ||
{'link': [1, 3], 'width': 3}, | ||
{'link': [1, 4], 'width': 3}], | ||
'nodes': [{'id': 0, | ||
'pos': [436.0933431058901, 431.72418500564186], | ||
'radius': 20, | ||
'color': '#16a085'}, | ||
{'id': 1, | ||
'pos': [404.62184898400426, 394.8158724310507], | ||
'radius': 20, | ||
'color': '#16a085'}, | ||
{'id': 2, | ||
'pos': [409.15148692745356, 438.08415417584683], | ||
'radius': 20, | ||
'color': '#16a085'}, | ||
{'id': 3, | ||
'pos': [439.27989436871223, 397.14932001193233], | ||
'radius': 20, | ||
'color': '#16a085'}, | ||
{'id': 4, | ||
'pos': [393.4680683212157, 420.63184247673917], | ||
'radius': 20, | ||
'color': '#16a085'}] | ||
} | ||
Furthermore, the configuration | ||
which was used to generate this figure will resemble | ||
|
||
.. code:: python | ||
config = { | ||
'Apply heat (wiggle)': False, | ||
'Charge strength': -30, | ||
'Center gravity': 0.1, | ||
'Link distance': 10, | ||
'Link width': 2, | ||
'Link alpha': 0.5, | ||
'Node size': 10, | ||
'Node stroke size': 0.5, | ||
'Node size exponent': 0.5, | ||
'Link width exponent': 0.5, | ||
'Collision': False, | ||
'Node fill': '#16a085', | ||
'Node stroke': '#000000', | ||
'Link stroke': '#7c7c7c', | ||
'Label stroke': '#000000', | ||
'Show labels': False, | ||
'Show singleton nodes': False, | ||
'Node size by strength': False, | ||
'Zoom': 1.5, | ||
'Min. link weight %': 0, | ||
'Max. link weight %': 100 | ||
} | ||
If the visualization was started from a Jupyter notebook, a picture of the stylized | ||
network will appear additionally | ||
|
||
.. figure:: img/figure_in_jupyter.png | ||
|
||
Stylized network in a Jupyter notebook. | ||
|
||
In order to reproduce this visualization, you may want to call the visualization function | ||
again with, passing the produced configuration. | ||
|
||
.. code:: python | ||
wulf.visualize(G, config=config) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
Starting a visualization | ||
------------------------ | ||
|
||
The interactive visualization is started from Python. | ||
In this module, we introduce the main functionalities | ||
supplied by the Python package. | ||
|
||
A visualization is started as follows. | ||
|
||
.. code:: python | ||
import networkx as nx | ||
from netwulf import visualize | ||
G = nx.barabasi_albert_graph(100,2) | ||
visualize(G) | ||
A visualization window is opened and the network can be stylized. |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
Interactive Visualization | ||
------------------------- | ||
|
||
TODO | ||
~~~~ | ||
|
||
I guess I would highlight how to use the visualization here: | ||
|
||
- explain what the controls do with the network | ||
- explain how to toggle/choose nodes (I find this confusing sometimes because you click on a node but the label is still there because you're still hovering | ||
- explain the network format when json is used | ||
- explain the network format when CSV is used | ||
- basically a GUI explanation |
This file was deleted.
Oops, something went wrong.