This notebook walks through basic code examples for integrating various packages with Neo4j, including py2neo, ipython-cypher, pandas, networkx, igraph, and jgraph.
py2neo is one of Neo4j's Python drivers. It offers a fully-featured interface for interacting with your data in Neo4j. Install py2neo with pip install py2neo.
Connect to Neo4j with the Graph class.
from py2neo import Graph
graph = Graph()
graph.delete_all()
Create nodes with the Node class. The first argument is the node's label. The remaining arguments are an arbitrary amount of node properties or key-value pairs.
from py2neo import Node
nicole = Node("Person", name="Nicole", age=24)
drew = Node("Person", name="Drew", age=20)
mtdew = Node("Drink", name="Mountain Dew", calories=9000)
cokezero = Node("Drink", name="Coke Zero", calories=0)
coke = Node("Manufacturer", name="Coca Cola")
pepsi = Node("Manufacturer", name="Pepsi")
graph.create(nicole | drew | mtdew | cokezero | coke | pepsi)
from scripts.vis import draw
options = {"Person": "name", "Drink": "name", "Manufacturer": "name"}
draw(graph, options)
P.S. - If you want to check out what's going on behind the scenes for the draw() function used above, take a look at scripts/vis.py.
Create relationships between nodes with the Relationship class.
from py2neo import Relationship
graph.create(Relationship(nicole, "LIKES", cokezero))
graph.create(Relationship(nicole, "LIKES", mtdew))
graph.create(Relationship(drew, "LIKES", mtdew))
graph.create(Relationship(coke, "MAKES", cokezero))
graph.create(Relationship(pepsi, "MAKES", mtdew))
draw(graph, options)
Retrieve Cypher query results with Graph.cypher.execute.
query = """
MATCH (person:Person)-[:LIKES]->(drink:Drink)
RETURN person.name AS name, drink.name AS drink
"""
data = graph.run(query)
for d in data:
print(d)
Pass parameters to Cypher queries by passing additional key-value arguments to Graph.cypher.execute. Parameters in Cypher are named and are wrapped in curly braces.
query = """
MATCH (p:Person)-[:LIKES]->(drink:Drink)
WHERE p.name = {name}
RETURN p.name AS name, AVG(drink.calories) AS avg_calories
"""
data = graph.run(query, name="Nicole")
for d in data:
print(d)
ipython-cypher exposes %cypher magic in Jupyter. Install ipython-cypher with pip install ipython-cypher.
%load_ext cypher
%cypher is intended for one-line Cypher queries and %%cypher is intended for multi-line Cypher queries. Placing %%cypher above a Cypher query will display that query's results.
%%cypher
MATCH (person:Person)-[:LIKES]->(drink:Drink)
RETURN person.name, drink.name, drink.calories
Cypher query results can be coerced to pandas data frames with the get_dataframe method. To assign Cypher query results to a variable, you need to use %cypher and separate lines with \. You'll first need to install pandas with pip install pandas.
results = %cypher MATCH (person:Person)-[:LIKES]->(drink:Drink) \
RETURN person.name AS name, drink.name AS drink
df = results.get_dataframe()
df
df.index
df.iloc[[1]]
df["name"]
Cypher query results can be coerced to NetworkX MultiDiGraphs, graphs that permit multiple edges between nodes, with the get_graph method. You'll first need to install NetworkX with pip install networkx.
import networkx as nx
%matplotlib inline
results = %cypher MATCH p = (:Person)-[:LIKES]->(:Drink) RETURN p
g = results.get_graph()
nx.draw(g)
g.nodes(data=True)
nx.degree(g)
Cypher query results can be imported into igraph with py2neo. You'll need to install igraph with pip install python-igraph. Query results should be returned as edgelists, as igraph has a method for building an igraph object from a list of tuples representing edges between nodes.
from py2neo import Graph as PGraph
from igraph import Graph as IGraph
neo4j = PGraph()
query = """
MATCH (person:Person)-[:LIKES]->(drink:Drink)
RETURN person.name AS source, drink.name AS target
"""
data = neo4j.run(query)
tups = []
for d in data:
tups.append((d["source"], d["target"]))
ig = IGraph.TupleList(tups)
ig
best = ig.vs.select(_degree = ig.maxdegree())["name"]
best
jgraph will plot tuple lists as 3D graphs.
import jgraph
jgraph.draw([(1, 2), (2, 3), (3, 4), (4, 1), (4, 5), (5, 2)])
data = graph.run("MATCH (n)-->(m) RETURN ID(n), ID(m)")
data = [tuple(x) for x in data]
jgraph.draw(data)