グラフデータをApache AGEでPostgreSQLに格納したら、それをビジュアライズしたいのが普通なので、Jaalを使ってインタラクティブにイジれるグラフにしてみた。
#!/usr/bin/env python3.11
# builtin modules
import json
import os
import sys
cur_python = f"python{sys.version_info[0]}.{sys.version_info[1]}"
# third party modules
try:
import pandas as pd
except ModuleNotFoundError:
os.system(f'{cur_python} -m pip install pandas')
import pandas as pd
try:
import psycopg as pg
from psycopg.rows import dict_row, namedtuple_row
except ModuleNotFoundError:
os.system(f'{cur_python} -m pip install psycopg')
import psycopg as pg
from psycopg.rows import dict_row, namedtuple_row
try:
from jaal import Jaal
except ModuleNotFoundError:
os.system(f'{cur_python} -m pip install jaal')
from jaal import Jaal
def main() -> None:
# load data
try:
with pg.connect(
host="localhost",
port=5455,
dbname="postgres",
user=os.environ.get('USER'),
password="passw0rd",
options="-c search_path=ag_catalog,'$user',public"
) as con:
with con.cursor(row_factory=namedtuple_row) as cur:
cur.execute('''SELECT *
FROM cypher('routes', $$
MATCH p = (a:airport)-[r:route]->(b:airport)
WHERE r.airline = "JL"
RETURN relationships(p), a, b
$$) as (r agtype, a agtype, b agtype)''')
data = cur.fetchall()
edges = []
for d in data:
route = json.loads(d.r[1:-len("::edge")-1])
ap_a = json.loads(d.a[:-len("::vertex")])
ap_b = json.loads(d.b[:-len("::vertex")])
edges.append({"from":ap_a["properties"]["code"], "to":ap_b["properties"]["code"], "title":route["properties"]["airline"]})
e_df = pd.DataFrame(edges)
except pg.OperationalError as e:
print(e)
sys.exit("Failed to connect to the database.")
aggreated = e_df.groupby(["from", "to"], as_index=False).agg({"title": lambda x: ",".join(x)})
Jaal(aggreated).plot(vis_opts={"height":"1600"})
if __name__ == "__main__":
main()