Python, Neo4j and Yworks

Wilson Chua
3 min readNov 20, 2022

--

The Pain Point: While Neo4J is incredible with network graphs DB, it has limited visualization. Here comes Yworks and Python to give us better visualization. My thanks to Sebastian Muller whos shared his code here:
https://gist.github.com/yGuy/9e0f35c2f5c9ef1473c9f39264640f02#file-yfiles_graphs_for_jupyter_nodes_2022-ipynb

For example:

Neo4J

To This:

Or To this:

YWorks output

To start, we need to install the required plugins (neo4j and yfiles_jupyter_graphs) using PIP install:

Open Jupyter notebook (/JupyterProjects/SecurityLogFiles/YWorksSampleCode.ipynb)

Hierarchical Layout

with driver.session(database=”neo4j”) as session:
graph= session.run(“match(a:ASNUM)<-[v:belongsTo]-(j:ISPName)<-[l:OwnedBy]-(n:Attacker)-[i:Incident]->(m:Target) where n.pagerank>400 return n,i,m,j,a limit 100”).graph()

from yfiles_jupyter_graphs import GraphWidget
GraphWidget(graph = graph)

organic edge router

Next: Adding colors, and changing the shapes of nodes

# Customization / adding styles
with driver.session(database=”neo4j”) as session:
graph= session.run(“match(a:ASNUM)<-[v:belongsTo]-(j:ISPName)<-[l:OwnedBy]-(n:Attacker)-[i:Incident]->(m:Target)
where n.pagerank>400 return a,j,n,i,m limit 100”).graph()

from yfiles_jupyter_graphs import GraphWidget

w = GraphWidget(graph = graph)
w.directed = False
w.set_graph_layout(“radial”)
w.set_neighborhood(2)
w.set_sidebar(enabled = False, start_with = “Neighborhood”)
w.set_overview(False)

w.set_node_color_mapping(lambda index, node : “red” if node[“properties”][“label”] == “Attacker:Node” else “blue”)
w.set_edge_color_mapping(lambda index, edge : “orange” if edge[“properties”][“protocol”] == “tcp” else “black”)
w.set_node_label_mapping(lambda index, node : node[“properties”][“IPv4”] + “\n” + str(node[“properties”][“pagerank”])
if node[“properties”][“label”] == “Attacker:Node” else node[“properties”][“label”])
w.set_node_scale_factor_mapping(lambda index, node : 1 + node[“properties”][“pagerank”] / 80
if node[“properties”][“label”] == “Attacker:Node” else 1)

w.show()

Using the Helper Method:

node_styles = {
“ASNUM”: {“color”:”orange”, “shape”:”ellipse”, “label”:”OrgName”},
“Attacker:Node”: {“color”:”red”, “shape”:”rectangle”, “label”:”IPv4"},
“ISPName”: {“color”:”#386664", “shape”:”rectangle”, “label”:”Name”},
“Node”: {“color”:”#498381", “shape”:”octagon”, “label”:”IPv4"},
“Node:Target”: {“color”:”blue”, “shape”:”ellipse”, “label”:”IPv4"},
“DEFAULT”: { “label”: “label”, “color”: “green” }
}

relationship_styles = {
“Incident”: {“color”:”orange”, “directed”: True},
“OwnedBy”: {“color”:”black”, “directed”: True },
“belongsTo”: {“color”:”red”, “directed”: True},
“DEFAULT”: { “label”: “label”, “directed”: True, “color”: “black” }
}

def createSecurityGraph(neo4jGraph):

def get_style(styles_dict, item):
return styles_dict.get(item[“properties”][“label”], styles_dict[“DEFAULT”])

def get_style_value(styles_dict, item, key):
style = get_style(styles_dict, item)
return style.get(key, styles_dict[“DEFAULT”][key])

def get_relationship_style(relationship):
return get_style(relationship_styles, relationship);

def get_label (styles_dict, item):
return item[“properties”][get_style_value(styles_dict, item, “label”)]

w = GraphWidget(graph = graph)
w.set_graph_layout(“radial”)
w.set_edge_color_mapping(lambda index, edge : get_relationship_style(edge)[“color”])
w.set_node_styles_mapping(lambda index, node : node_styles.get(node[“properties”][“label”], {}))
w.set_node_label_mapping(lambda index, node : get_label(node_styles, node))
w.set_edge_label_mapping(lambda index, edge : get_label(relationship_styles, edge))
w.set_directed_mapping(lambda index, edge : get_style_value(relationship_styles, edge, “directed”))

return w.show()

Now we look at communities :

from neo4j import GraphDatabase
driver = GraphDatabase.driver(db, auth=basic_auth(user=”neo4j”, password=pwd))

with driver.session(database=”neo4j”) as session:
graph = session.run(“match (j:ISPName)<-[l:OwnedBy]-(n:Attacker)-[i:Incident]->(m:Target) where n.louvain=27206 return j,n,i,m,l limit 500”).graph()

createSecurityGraph(graph)

--

--