Quick Start#
This library introduces a Graph object. It will contain all the nodes and
connections of your graph. It can also contain any additional data.
A Graph can be directed (the link between two nodes has a single
direction) or undirected (any link between two nodes is symmetrical). By
default, it is directed.
from galaxy_graph import Graph
# Family tree can be considered as directed graph, a relationship is not symmetrical
family_tree = Graph(
data="This graph stores my family tree. As I did not specify `is_directed`, it is directed, which is nice for a family graph"
) # create a directed graph with a description in its data
# A hiking trail with nodes for intersection, relationships are symmetrical
hiking_trails = Graph(
is_directed=False,
) # create a undirected graph without any data
There is also a Node object, that can contain any data.
from galaxy_graph import Node
# In these example, data contains a dictionary, but data can contains any value !
# For the family tree
michel = Node(data={"Name": "Michel", "age": 48})
alberto = Node(data={"Name": "Alberto", "age": 46})
alice = Node(data={"Name": "Alice", "age": 20})
# For the hiking trail
city_entrance = Node(data={"x": 5, "y": 10})
rocky_promontory = Node(data={"x": 18, "y": 13})
oak_forest = Node(data={"x": 10, "y": 10})
lake = Node(data={"x": -3, "y": 4})
Without Connection, there is no link between Node and your graphs would
be boring… Again, these can contain any data.
from galaxy_graph import Connection
# For the hiking trail
straight_road = Connection(data={"ground type": "dirt"})
You can then add your nodes to the graph and connect them.
hiking_trails.add(city_entrance) # add city entrance to the graph
city_entrance.connect(straight_road, rocky_promontory) # the city entrance
# and the rocky promontory are linked together. The straight road allows
# traversal in both direction because hiking_trails is an undirected graph.
Warning
Adding a node to the graph is mandatory for adding connection to it. Any node connected to this one will be automatically added to the graph.
Note
It is also possible to create the connection in the connect call.
rocky_promontory.connect(
Connection(data={"ground type": "dirt"}),
oak_forest,
)
city_entrance.connect(
Connection(data={"ground type": "asphalt"}),
oak_forest,
)
oak_forest.connect(
Connection(data={"ground type": "dirt"}),
lake,
)
lake.connect(
Connection(data={"ground type": "dirt"}),
city_entrance,
)
family_tree.add(michel)
michel.connect(Connection(data="is married to"), alberto) # Michel and Alberto are married
alberto.connect(Connection(data="is married to"), michel) # symmetrical link
# here, so we add a connection in the other direction.
michel.connect(Connection(data="is parent of"), alice)
alberto.connect(Connection(data="is parent of"), alice)
alice.connect(Connection(data="is child of"), michel)
alice.connect(Connection(data="is child of"), alberto)
Warning
As family tree is a directed graph, the connection Michel->Alberto is different than the connection Alberto->Michel.
michel_alberto = Connection(data="is married to")
michel.connect(michel_alberto, alberto)
alberto.connect(michel_alberto, michel) # will fail: the connection is
# already used.
If you run all the python code above, your hiking_trails graph will look like this:
---
title: Hiking trails
---
graph TD
A[City entrance] <-->|dirt road| B[Rocky promontory]
B <-->|dirt road| C[Oak forest]
C <-->|dirt road| D[Lake]
D <-->|dirt road| A
A <-->|asphalt road| C
For the family tree, the resulting graph will be:
---
title: Family tree
---
graph TD
Michel -->|is married to| Alberto
Alberto -->|is married to| Michel
Michel -->|is parent of| Alice
Alberto -->|is parent of| Alice
Alice -->|is child of| Michel
Alice -->|is child of| Alberto