HyperNetX + Graphistry = 💪💪💪#
You can quickly explore HyperNetX graphs using Graphistry through the below sample class.
PNNL’s HyperNetX is a new Python library for manipulating hypergraphs: graphs where an edge may connect any number of nodes. The below helper class converts HyperNetX graphs into 2-edge graphs (node/edge property tables as Panda dataframes ) in two different modes:
hypernetx_to_graphistry_bipartite(hnx_graph)
:Turn every hyperedge and hypernode into nodes. They form a bipartite graph: whenever a hyperedge includes a hypernode, create an edge from the hyperedge’s node to the hypernode’s node.
ex: Hyperedge
0: ['a', 'b', 'c']
=> edge(0, 'a')
, edge(0, 'b')
, edge(0, 'c')
hypernetx_to_graphistry_nodes(hnx_graph)
:Turn every hypernode into a node, and whenever two hypernodes share the same hyperedge, create an edge between their corresponding nodes
To emphasize that edges are undirect, the library sets the edge curvature to 0 (straight)
ex: Hyperedge
0: ['a', 'b', 'c']
=> edge('a', 'b')
, edge('a', 'c')
, edge('b', 'c')
Install#
Dependencies already preinstalled in Graphistry Core distributions
[1]:
# ! pip install hypernetx -q
# ! pip install graphistry -q
Lib#
[2]:
import pandas as pd
class HyperNetXG:
def __init__(self, graphistry):
self.graphistry = graphistry
def normalize_id(self, id):
t = type(id)
if t == float or t == int:
return '__id__' + str(id)
return str(id)
def hypernetx_to_graphistry_bipartite(self, h):
nodes_df = pd.concat(
[pd.DataFrame({
'node': [self.normalize_id(x) for x in list(H.nodes)],
'type': 'hypernode'}),
pd.DataFrame({
'node': [self.normalize_id(x) for x in H.edges],
'type': 'hyperedge'})],
ignore_index=True,
sort=False)
edges_df = pd.concat(
[ pd.DataFrame({'src': [], 'dst': []}) ] +
[
pd.DataFrame({
'src': self.normalize_id(k),
'dst': [self.normalize_id(x) for x in list(es)]
})
for k, es in H.incidence_dict.items()
], ignore_index=True, sort=False)
return self.graphistry.bind(
source='src',
destination='dst',
node='node').nodes(nodes_df).edges(edges_df)
def __hyperedge_to_graph(self, k, es):
lst = list(es)
edges_df = pd.concat([
pd.DataFrame({'src': [], 'dst': [], 'hyperedge': []})] + [
pd.DataFrame({
'src': self.normalize_id(lst[i]),
'dst': [self.normalize_id(x) for x in lst[i+1:]],
'hyperedge': self.normalize_id(k)})
for i in range(0, len(lst))
], ignore_index=True, sort=False)
return edges_df
def hypernetx_to_graphistry_nodes(self, h):
hg = self.hypernetx_to_graphistry_bipartite(h)
nodes_df = pd.DataFrame({
'node': [self.normalize_id(x) for x in list(h.nodes)],
'type': 'hypernode'})
edges_df = pd.concat(
[pd.DataFrame({'src': [], 'dst': [], 'hyperedge': []})] +
[
self.__hyperedge_to_graph(k, es)
for (k, es) in h.incidence_dict.items()
])
return self.graphistry.bind(
source='src',
destination='dst',
node='node').settings(url_params={'edgeCurvature': 0}).nodes(nodes_df).edges(edges_df)
Demo#
Init#
[3]:
import hypernetx as hnx
import graphistry
# To specify Graphistry account & server, use:
# graphistry.register(api=3, username='...', password='...', protocol='https', server='hub.graphistry.com')
# For more options, see https://github.com/graphistry/pygraphistry#configure
scenes = [
('FN', 'TH'),
('TH', 'JV'),
('BM', 'FN', 'JA'),
('JV', 'JU', 'CH', 'BM'),
('JU', 'CH', 'BR', 'CN', 'CC', 'JV', 'BM'),
('TH', 'GP'),
('GP', 'MP'),
('MA', 'GP')
]
H = hnx.Hypergraph(dict(enumerate(scenes)))
hg = HyperNetXG(graphistry)
hypernetx_to_graphistry_bipartite#
Flatten to Pandas Dataframes / Graphistry and inspect:
[4]:
g = hg.hypernetx_to_graphistry_bipartite(H)
g._nodes.sample(3)
[4]:
node | type | |
---|---|---|
18 | __id__5 | hyperedge |
17 | __id__4 | hyperedge |
15 | __id__2 | hyperedge |
[5]:
g._edges.sample(3)
[5]:
src | dst | |
---|---|---|
18 | __id__5 | TH |
20 | __id__6 | MP |
10 | __id__3 | CH |
[6]:
g.plot()
[6]:
[7]:
hg.hypernetx_to_graphistry_bipartite(H.dual())._edges.sample(3)
[7]:
src | dst | |
---|---|---|
16 | __id__4 | CN |
17 | __id__4 | BR |
14 | __id__4 | BM |
[8]:
hg.hypernetx_to_graphistry_bipartite(H.dual()).plot()
[8]:
hypernetx_to_graphistry_nodes#
[9]:
g = hg.hypernetx_to_graphistry_nodes(H)
g._edges.sample(3)
[9]:
src | dst | hyperedge | |
---|---|---|---|
16 | BM | CN | __id__4 |
0 | JA | BM | __id__2 |
2 | JU | CH | __id__3 |
[10]:
hg.hypernetx_to_graphistry_nodes(H).plot()
[10]:
[11]:
hg.hypernetx_to_graphistry_nodes(H.dual()).plot()
[11]: