PyGraphistry <> Titan graph#
In this notebook, we demonstrate how to create and modify a Titan graph in python, and then visualize the result using Graphistry’s visual graph explorer.
We assume the gremlin server for our Titan graph is hosted locally on port 8182#
This notebook utilizes the python modules aiogremlin and asyncio.
The GremlinClient class of aiogremlin communicates asynchronously with the gremlin server using websockets via asyncio coroutines.
This implementation allows you to submit additional requests to the server before any responses are recieved, which is much faster than synchronous request / response cycles.
For more information about these modules, please visit:
[1]:
import asyncio
import aiogremlin
[2]:
# Create event loop and initialize gremlin client
loop = asyncio.get_event_loop()
client = aiogremlin.GremlinClient(url='ws://localhost:8182/', loop=loop) # Default url
Functions for graph modification#
[3]:
@asyncio.coroutine
def add_vertex_routine(name, label):
yield from client.execute("graph.addVertex(label, l, 'name', n)", bindings={"l":label, "n":name})
def add_vertex(name, label):
loop.run_until_complete(add_vertex_routine(name, label))
@asyncio.coroutine
def add_relationship_routine(who, relationship, whom):
yield from client.execute("g.V().has('name', p1).next().addEdge(r, g.V().has('name', p2).next())", bindings={"p1":who, "p2":whom, "r":relationship})
def add_relationship(who, relationship, whom):
loop.run_until_complete(add_relationship_routine(who, relationship, whom))
@asyncio.coroutine
def remove_all_vertices_routine():
resp = yield from client.submit("g.V()")
results = []
while True:
msg = yield from resp.stream.read();
if msg is None:
break
if msg.data is None:
break
for vertex in msg.data:
yield from client.submit("g.V(" + str(vertex['id']) + ").next().remove()")
def remove_all_vertices():
results = loop.run_until_complete(remove_all_vertices_routine())
@asyncio.coroutine
def remove_vertex_routine(name):
return client.execute("g.V().has('name', n).next().remove()", bindings={"n":name})
def remove_vertex(name):
return loop.run_until_complete(remove_vertex_routine(name));
Functions for translating a graph to node and edge lists:#
- Currently, our API can only upload data from a pandas DataFrame, but we plan to implement more flexible uploads in the future.
- For now, we can rely on the following functions to create the necessary DataFrames from our graph.
[4]:
@asyncio.coroutine
def get_node_list_routine():
resp = yield from client.submit("g.V().as('node')\
.label().as('type')\
.select('node').values('name').as('name')\
.select('name', 'type')")
results = [];
while True:
msg = yield from resp.stream.read();
if msg is None:
break;
if msg.data is None:
break;
else:
results.extend(msg.data)
return results
def get_node_list():
results = loop.run_until_complete(get_node_list_routine())
return results
@asyncio.coroutine
def get_edge_list_routine():
resp = yield from client.submit("g.E().as('edge')\
.label().as('relationship')\
.select('edge').outV().values('name').as('source')\
.select('edge').inV().values('name').as('dest')\
.select('source', 'relationship', 'dest')")
results = [];
while True:
msg = yield from resp.stream.read();
if msg is None:
break;
if msg.data is None:
break;
else:
results.extend(msg.data)
return results
def get_edge_list():
results = loop.run_until_complete(get_edge_list_routine())
return results
Let’s start with an empty graph:#
[5]:
remove_all_vertices()
And then populate it with the Graphistry team members and some of thier relationships:#
[6]:
add_vertex("Paden", "Person")
add_vertex("Thibaud", "Person")
add_vertex("Leo", "Person")
add_vertex("Matt", "Person")
add_vertex("Brian", "Person")
add_vertex("Quinn", "Person")
add_vertex("Paul", "Person")
add_vertex("Lee", "Person")
add_vertex("San Francisco", "Place")
add_vertex("Oakland", "Place")
add_vertex("Berkeley", "Place")
add_vertex("Turkey", "Thing")
add_vertex("Rocks", "Thing")
add_vertex("Motorcycles", "Thing")
add_relationship("Paden", "lives in", "Oakland")
add_relationship("Quinn", "lives in", "Oakland")
add_relationship("Thibaud", "lives in", "Berkeley")
add_relationship("Matt", "lives in", "Berkeley")
add_relationship("Leo", "lives in", "San Francisco")
add_relationship("Paul", "lives in", "San Francisco")
add_relationship("Brian", "lives in", "Oakland")
add_relationship("Paden", "eats", "Turkey")
add_relationship("Quinn", "cooks", "Turkey")
add_relationship("Thibaud", "climbs", "Rocks")
add_relationship("Matt", "climbs", "Rocks")
add_relationship("Brian", "rides", "Motorcycles")
add_vertex("Graphistry", "Work")
add_relationship("Paden", "works at", "Graphistry")
add_relationship("Thibaud", "works at", "Graphistry")
add_relationship("Matt", "co-founded", "Graphistry")
add_relationship("Leo", "co-founded", "Graphistry")
add_relationship("Paul", "works at", "Graphistry")
add_relationship("Quinn", "works at", "Graphistry")
add_relationship("Brian", "works at", "Graphistry")
Now, let’s convert our graph database to a pandas DataFrame, so it can be uploaded into our tool:#
[7]:
import pandas
[8]:
nodes = pandas.DataFrame(get_node_list())
edges = pandas.DataFrame(get_edge_list())
And color the nodes based on their “type” property:#
[9]:
# Assign different color to each type in a round robin fashion.
# For more information and coloring options please visit: https://graphistry.github.io/docs/legacy/api/0.9.2/api.html
unique_types = list(nodes['type'].unique())
nodes['color'] = nodes['type'].apply(lambda x: unique_types.index(x) % 11)
[10]:
nodes
[10]:
name | type | color | |
---|---|---|---|
0 | Paden | Person | 0 |
1 | Quinn | Person | 0 |
2 | Turkey | Thing | 1 |
3 | Thibaud | Person | 0 |
4 | Matt | Person | 0 |
5 | Leo | Person | 0 |
6 | Berkeley | Place | 2 |
7 | Rocks | Thing | 1 |
8 | Motorcycles | Thing | 1 |
9 | Graphistry | Work | 3 |
10 | Lee | Person | 0 |
11 | Oakland | Place | 2 |
12 | Brian | Person | 0 |
13 | Paul | Person | 0 |
14 | San Francisco | Place | 2 |
[11]:
edges
[11]:
dest | relationship | source | |
---|---|---|---|
0 | Oakland | lives in | Paden |
1 | Turkey | eats | Paden |
2 | Graphistry | works at | Paden |
3 | Oakland | lives in | Quinn |
4 | Turkey | cooks | Quinn |
5 | Graphistry | works at | Quinn |
6 | Berkeley | lives in | Thibaud |
7 | Rocks | climbs | Thibaud |
8 | Graphistry | works at | Thibaud |
9 | Berkeley | lives in | Matt |
10 | Rocks | climbs | Matt |
11 | Graphistry | co-founded | Matt |
12 | San Francisco | lives in | Leo |
13 | Graphistry | co-founded | Leo |
14 | Oakland | lives in | Brian |
15 | Motorcycles | rides | Brian |
16 | Graphistry | works at | Brian |
17 | San Francisco | lives in | Paul |
18 | Graphistry | works at | Paul |
Finally, let’s vizualize the results!#
[12]:
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
g = graphistry.bind(source="source", destination="dest", node='name', point_color='color', edge_title='relationship')
g.plot(edges, nodes)
[12]:
[ ]: