Helios Network Visualization¶

About¶
Overview¶
What is Helios ?¶
Mission Statement¶
The purpose of Helios is to make it easy to perform graph/network Visualization …
…
…
License¶
Helios is distributed under the MIT License
Credits¶
Go to Community page to see who have been involved in the development of Helios.
Bug reports and support¶
Please report any issues via https://github.com/fury-gl/helios/issues. All types of issues are welcome including bug reports, documentation typos, feature requests and so on.
License¶
Blog¶
Installation¶
Helios supports Python 3.7+.
Dependencies¶
The mandatory dependencies are:
numpy >= 1.7.1
vtk >= 8.1.0
fury
The optional dependencies are:
opencv
cugraph
Installation via Source¶
Step 1. Get the latest source by cloning this repo
git clone https://github.com/fury-gl/helios.git
Step 2. Install requirements
pip install -r requirements.txt
Step 3. Install helios via
pip install -e .
Step 4: Enjoy!
Running the Tests¶
Let’s install all required packages for the running the test
pip install -r requirements.txt
pip install -r requirements_dev.txt
There are two ways to run Helios tests:
From the command line. You need to be on the Helios package folder
pytest -svv helios
To run a specific test file
pytest -svv helios/tests/test_actor.py
To run a specific test directory
pytest -svv helios/tests
To run a specific test function
pytest -svv -k "test_my_function_name"
Running the Tests Offscreen¶
Helios is based on VTK which uses OpenGL for all its rendering. For a headless rendering, we recommend to install and use Xvfb software on linux or OSX. Since Xvfb will require an X server (we also recommend to install XQuartz package on OSX). After Xvfb is installed you have 2 options to run Helios tests:
First option
export DISPLAY=:0
Xvfb :0 -screen 1920x1080x24 > /dev/null 2>1 &
pytest -svv fury
Second option
export DISPLAY=:0
xvfb-run --server-args="-screen 0 1920x1080x24" pytest -svv fury
Populating our Documentation¶
In our docs
folder structure above:
source
is the folder that contains all*.rst
files.tutorials
is the directory where we have all python scripts that describe how to use the api.examples
being the Helios app showcases.
Building the documentation¶
Step 1. Install all required packages for the documentation generation
pip install -U -r requirements.txt
pip install -U -r requirements_docs_sys.txt
Step 2. Go to the docs
folder and run the following command to generate it (Linux and macOS)
make -C . clean && make -C . html
To generate the documentation without running the examples
make -C . clean && make -C . html-no-examples
or under Windows
make clean
make html
To generate the documentation without running the examples under Windows
make clean
make html-no-examples
Step 3. Congratulations! the build
folder has been generated! Go to build/html
and open with browser index.html
to see your generated documentation.
Examples¶
Note
Click here to download the full example code
Visualize Interdisciplinary map of the journals network¶
The goal of this app is to show an overview of the journals network structure as a complex network. Each journal is shown as a node and their connections indicates a citation between two of them.
First, let’s import some useful functions
from os.path import join as pjoin
from fury import colormap as cmap
from fury.window import record
import numpy as np
Then let’s download some available datasets.
from fury.data.fetcher import fetch_viz_wiki_nw
from helios import NetworkDraw
from helios.layouts.force_directed import HeliosFr
files, folder = fetch_viz_wiki_nw()
categories_file, edges_file, positions_file = sorted(files.keys())
Out:
Dataset is already in place. If you want to fetch it again please first remove the folder /home/devmessias/.fury/examples/wiki_nw
More information about complex networks can be found in this papers: https://arxiv.org/abs/0711.3199
We read our datasets
positions = np.loadtxt(pjoin(folder, positions_file))
positions = np.random.normal(scale=10, size=positions.shape)
categories = np.loadtxt(pjoin(folder, categories_file), dtype=str)
edges = np.loadtxt(pjoin(folder, edges_file), dtype=int)
We attribute a color to each category of our dataset which correspond to our nodes colors.
category2index = {category: i
for i, category in enumerate(np.unique(categories))}
index2category = np.unique(categories)
categoryColors = cmap.distinguishable_colormap(nb_colors=len(index2category))
colors = np.array([categoryColors[category2index[category]]
for category in categories])
We define our node size
radii = 1 + np.random.rand(len(positions))
Lets create our edges now. They will indicate a citation between two nodes. OF course, the colors of each edges will be an interpolation between the two node that it connects.
#edgesPositions = []
edgesColors = []
for source, target in edges:
#edgesPositions.append(np.array([positions[source], positions[target]]))
edgesColors.append(np.array([colors[source], colors[target]]))
#edgesPositions = np.array(edgesPositions)
edgesColors = np.average(np.array(edgesColors), axis=1)
Our data preparation is ready, it is time to visualize them all. We start to build 2 actors that we represent our data : sphere_actor for the nodes and lines_actor for the edges.
network_draw = NetworkDraw(
positions=positions,
colors=colors,
scales=4,
node_edge_width=0,
edge_line_color=edgesColors,
marker='3d',
edges=edges,
)
layout = HeliosFr(edges, network_draw, update_interval_workers=10)
layout.start()
The final step ! Visualize and save the result of our creation! Please, switch interactive variable to True if you want to visualize it.
interactive = False
if not interactive:
import time
time.sleep(10)
layout.stop()
if interactive:
network_draw.showm.initialize()
network_draw.showm.start()
record(
network_draw.showm.scene, out_path='viz_helios.png', size=(600, 600))

Total running time of the script: ( 0 minutes 14.288 seconds)
Note
Click here to download the full example code
Minmum Distortion Embedding with Anchored Constraints¶

import numpy as np
import time
from fury.window import record
from helios import NetworkDraw
from helios.layouts.mde import MDE
# from https://github.com/cvxgrp/pymde/blob/main/examples/anchor_constraints.ipynb
depth = 9
n_items = 2**(depth + 1) - 1
edges = []
stack = [0]
while stack:
root = stack.pop()
first_child = root*2 + 1
second_child = root*2 + 2
if first_child < n_items:
edges.append([root, first_child])
stack.append(first_child)
if second_child < n_items:
edges.append([root, second_child])
stack.append(second_child)
# these are the indices of the nodes that we will pin in place
anchors = np.arange(2**depth) + 2**depth - 1
radius = 20
# pin the root to be at (0, 0), and the leaves to be spaced uniformly on a circle
angles = np.linspace(0, 2*np.pi, anchors.shape[0] + 1)[1:]
anchors_pos = radius * np.stack([np.sin(angles), np.cos(angles)], axis=1)
centers = np.random.normal(size=(n_items, 2))*5
centers[anchors] = anchors_pos.copy()
network_draw = NetworkDraw(
positions=centers,
scales=.4,
node_edge_width=0,
#colors=(1, 0,0),
edge_line_opacity=.5,
edge_line_color=(0, 0, 0),
marker='3d',
window_size=(500, 500),
edges=np.array(edges)
)
mde = MDE(
np.array(edges), network_draw,
constraint_name='anchored',
anchors=anchors.astype('float32'),
anchors_pos=anchors_pos.astype('float32'),
use_shortest_path=True
)
interactive = False
if not interactive:
mde.start(
100, 1, 300,
record_positions=False, without_iren_start=True)
time.sleep(30)
mde.stop()
else:
mde.start(
3, 300, 1,
record_positions=True, without_iren_start=False)
if interactive:
network_draw.showm.initialize()
network_draw.showm.start()
record(
network_draw.showm.scene, out_path='viz_mde.png', size=(600, 600))
Total running time of the script: ( 0 minutes 30.180 seconds)
API¶
Layouts |
|
Contributing¶
Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given.
You can contribute in many ways:
Types of Contributions¶
Report Bugs¶
Report bugs at https://github.com/fury-gl/helios/issues.
If you are reporting a bug, please include:
Any details about your local setup that might be helpful in troubleshooting.
Detailed steps to reproduce the bug.
Fix Bugs¶
Look through the GitHub issues for bugs. Anything tagged with “bug” is open to whoever wants to implement it.
Implement Features¶
Look through the GitHub issues for features. Anything tagged with “feature” is open to whoever wants to implement it.
Write Documentation¶
Helios could always use more documentation, whether as part of the official Helios docs, in docstrings, or even on the web in blog posts, articles, and such. Helios uses [Sphinx](http://www.sphinx-doc.org/en/stable/index.html) to generate documentation. Please follow the [numpy coding style](https://numpydoc.readthedocs.io/en/latest/format.html#docstring-standard) - and of course - [PEP8](https://www.python.org/dev/peps/pep-0008/) for docstring documentation.
Submit Feedback¶
The best way to send feedback is to file an issue at https://github.com/fury-gl/helios/issues.
If you are proposing a feature:
Explain in detail how it would work.
Keep the scope as narrow as possible, to make it easier to implement.
Remember that this is a volunteer-driven project, and that contributions are welcome :)
Get Started!¶
Pull Request Guidelines¶
Before you submit a pull request, check that it meets these guidelines:
The pull request should include tests.
If the pull request adds functionality, the docs should be updated. Put your new functionality into a function with a docstring, and add the feature to the list in README.md.
The pull request should work for Python3.7, 3.8, 3.9 and for PyPy.
Publishing Releases¶
Checklist before Releasing¶
Review the open list of Helios issues. Check whether there are outstanding issues that can be closed, and whether there are any issues that should delay the release. Label them !
Review and update the release notes. Review and update the
Changelog
file. Get a partial list of contributors with something like:git shortlog -nse v0.1.0..
where
v0.1.0
was the last release tag name.Then manually go over
git shortlog v0.1.0..
to make sure the release notes are as complete as possible and that every contributor was recognized.Use the opportunity to update the
.mailmap
file if there are any duplicate authors listed fromgit shortlog -ns
.Add any new authors to the
AUTHORS
file.Check the copyright years in
docs/source/conf.py
andLICENSE
Check the examples and tutorial - we really need an automated check here.
Make sure all tests pass on your local machine (from the
<helios root>
directory):cd .. pytest -s --verbose --doctest-modules helios cd helios # back to the root directory
Check the documentation doctests:
cd docs make -C . html cd ..
The release should now be ready.
Doing the release¶
Update release-history.rst in the documentation if you have not done so already. You may also highlight any additions, improvements, and bug fixes.
Type git status and check that you are on the master branch with no uncommitted code.
Now it’s time for the source release. Mark the release with an empty commit, just to leave a marker. It makes it easier to find the release when skimming through the git history:
git commit --allow-empty -m "REL: vX.Y.Z"
Tag the commit:
git tag -am 'Second public release' vX.Y.Z # Don't forget the leading v
This will create a tag named vX.Y.Z. The -a flag (strongly recommended) opens up a text editor where you should enter a brief description of the release.
Verify that the __version__ attribute is correctly updated:
import helios helios.__version__ # should be 'X.Y.Z'
Incidentally, once you resume development and add the first commit after this tag, __version__ will take on a value like X.Y.Z+1.g58ad5f7, where +1 means “1 commit past version X.Y.Z” and 58ad5f7 is the first 7 characters of the hash of the current commit. The letter g stands for “git”. This is all managed automatically by versioneer and in accordance with the specification in PEP 440.
Push the new commit and the tag to master:
git push origin master git push origin vX.Y.Z
Register for a PyPI account and Install twine, a tool for uploading packages to PyPI:
python3 -m pip install --upgrade twine
Remove any extraneous files:
git clean -dfx
If you happen to have any important files in your project directory that are not committed to git, move them first; this will delete them!
Publish a release on PyPI:
python setup.py sdist python setup.py bdist_wheel twine upload dist/*
Check how everything looks on pypi - the description, the packages. If necessary delete the release and try again if it doesn’t look right.
Set up maintenance / development branches
If this is this is a full release you need to set up two branches, one for further substantial development (often called ‘trunk’) and another for maintenance releases.
Branch to maintenance:
git co -b maint/X.Y.Z
Push with something like
git push upstream-rw maint/0.6.x --set-upstream
Start next development series:
git co main-master
Next merge the maintenace branch with the “ours” strategy. This just labels the maintenance branch info.py edits as seen but discarded, so we can merge from maintenance in future without getting spurious merge conflicts:
git merge -s ours maint/0.6.x
Push with something like
git push upstream-rw main-master:master
If this is just a maintenance release from
maint/0.6.x
or similar, just tag and set the version number to - say -0.6.2.dev
.Push the tag with
git push upstream-rw 0.6.0