ontograph¶
A module adding graphing functionality to ontopy.ontology
OntoGraph
¶
A mixin class used by ontopy.ontology.Ontology that adds functionality for generating graph representations of the ontology.
get_dot_graph(self, root=None, graph=None, relations='is_a', leafs=None, parents=False, style=None, edgelabels=True, constraint=False)
¶
Returns a pydot graph object for visualising the ontology.
Parameters¶
root : None | string | owlready2.ThingClass instance
Name or owlready2 entity of root node to plot subgraph
below. If root
is None, all classes will be included in the
subgraph.
graph : None | pydot.Dot instance
Pydot graph object to plot into. If None, a new graph object
is created using the keyword arguments.
relations : True | str | sequence
Sequence of relations to visualise. If True, all relations are
included.
leafs : None | sequence
A sequence of leaf node names for generating sub-graphs.
parents : bool | str
Whether to include parent nodes. If parents
is a string,
only parent nodes down to the given name will included.
style : None | dict | "uml"
A dict mapping the name of the different graphical elements
to dicts of pydot style settings. Supported graphical elements
include:
- graph : overall settings pydot graph
- class : nodes for classes
- individual : nodes for invididuals
- is_a : edges for is_a relations
- equivalent_to : edges for equivalent_to relations
- disjoint_with : edges for disjoint_with relations
- inverse_of : edges for inverse_of relations
- relations : with relation names
XXX
- other : edges for other relations and restrictions
If style is None, a very simple default style is used.
Some pre-defined styles can be selected by name (currently
only "uml").
edgelabels : bool | dict
Whether to add labels to the edges of the generated graph.
It is also possible to provide a dict mapping the
full labels (with cardinality stripped off for restrictions)
to some abbriviations.
constraint : None | bool
Note: This method requires pydot.
Source code in ontopy/ontograph.py
def get_dot_graph(self, root=None, graph=None, relations='is_a',
leafs=None, parents=False, style=None,
edgelabels=True, constraint=False):
"""Returns a pydot graph object for visualising the ontology.
Parameters
----------
root : None | string | owlready2.ThingClass instance
Name or owlready2 entity of root node to plot subgraph
below. If `root` is None, all classes will be included in the
subgraph.
graph : None | pydot.Dot instance
Pydot graph object to plot into. If None, a new graph object
is created using the keyword arguments.
relations : True | str | sequence
Sequence of relations to visualise. If True, all relations are
included.
leafs : None | sequence
A sequence of leaf node names for generating sub-graphs.
parents : bool | str
Whether to include parent nodes. If `parents` is a string,
only parent nodes down to the given name will included.
style : None | dict | "uml"
A dict mapping the name of the different graphical elements
to dicts of pydot style settings. Supported graphical elements
include:
- graph : overall settings pydot graph
- class : nodes for classes
- individual : nodes for invididuals
- is_a : edges for is_a relations
- equivalent_to : edges for equivalent_to relations
- disjoint_with : edges for disjoint_with relations
- inverse_of : edges for inverse_of relations
- relations : with relation names
XXX
- other : edges for other relations and restrictions
If style is None, a very simple default style is used.
Some pre-defined styles can be selected by name (currently
only "uml").
edgelabels : bool | dict
Whether to add labels to the edges of the generated graph.
It is also possible to provide a dict mapping the
full labels (with cardinality stripped off for restrictions)
to some abbriviations.
constraint : None | bool
Note: This method requires pydot.
"""
warnings.warn(
"""The ontopy.ontology.get_dot_graph() method is deprecated.
Use ontopy.ontology.get_graph() instead.
This requires that you install graphviz instead of the old
pydot package.""", DeprecationWarning)
# FIXME - double inheritance leads to dublicated nodes. Make sure
# to only add a node once!
import pydot
from ontopy.ontology import NoSuchLabelError
if style is None or style == 'default':
style = self._default_style
elif style == 'uml':
style = self._uml_style
graph = self._get_dot_graph(root=root, graph=graph,
relations=relations, leafs=leafs,
style=style, edgelabels=edgelabels)
# Add parents
# FIXME - facture out into an recursive function to support
# multiple inheritance
if parents and root:
r = self.get_by_label(root) if isinstance(root, str) else root
while True:
parent = r.is_a.first()
if (parent is None or parent is owlready2.Thing):
break
label = asstring(parent)
if self.is_defined(label):
node = pydot.Node(label, **style.get('defined_class', {}))
# If label contains a hyphen, the node name will
# be quoted (bug in pydot?). To work around, set
# the name explicitly...
node.set_name(label)
else:
node = pydot.Node(label, **style.get('class', {}))
node.set_name(label)
graph.add_node(node)
if relations is True or 'is_a' in relations:
kw = style.get('is_a', {}).copy()
if isinstance(edgelabels, dict):
kw['label'] = edgelabels.get('is_a', 'is_a')
elif edgelabels:
kw['label'] = 'is_a'
rootnode = graph.get_node(asstring(r))[0]
edge = pydot.Edge(rootnode, node, **kw)
graph.add_edge(edge)
if (isinstance(parents, str) and label == parents):
break
r = parent
# Add edges
for node in graph.get_nodes():
try:
entity = self.get_by_label(node.get_name())
except (KeyError, NoSuchLabelError):
continue
# Add is_a edges
targets = [e for e in entity.is_a if not isinstance(e, (
owlready2.ThingClass, owlready2.ObjectPropertyClass,
owlready2.PropertyClass))]
self._get_dot_add_edges(
graph, entity, targets, 'relations',
relations,
# style=style.get('relations', style.get('other', {})),
style=style.get('other', {}),
edgelabels=edgelabels,
constraint=constraint,
)
# Add equivalent_to edges
if relations is True or 'equivalent_to' in relations:
self._get_dot_add_edges(
graph, entity, entity.equivalent_to, 'equivalent_to',
relations, style.get('equivalent_to', {}),
edgelabels=edgelabels,
constraint=constraint,
)
# disjoint_with
if hasattr(entity, 'disjoints') and (
relations is True or 'disjoint_with' in relations):
self._get_dot_add_edges(
graph, entity, entity.disjoints(), 'disjoint_with',
relations, style.get('disjoint_with', {}),
edgelabels=edgelabels,
constraint=constraint,
)
# Add inverse_of
if (hasattr(entity, 'inverse_property') and
(relations is True or 'inverse_of' in relations) and
entity.inverse_property not in (None, entity)):
self._get_dot_add_edges(
graph, entity, [entity.inverse_property], 'inverse_of',
relations, style.get('inverse_of', {}),
edgelabels=edgelabels,
constraint=constraint,
)
return graph
get_dot_relations_graph(self, graph=None, relations='is_a', style=None)
¶
Returns a disjoined graph of all relations.
This method simply calls get_dot_graph() with all root relations. All arguments are passed on.
Source code in ontopy/ontograph.py
def get_dot_relations_graph(self, graph=None, relations='is_a',
style=None):
"""Returns a disjoined graph of all relations.
This method simply calls get_dot_graph() with all root relations.
All arguments are passed on.
"""
rels = tuple(self.get_relations())
roots = [relation for relation in rels
if not any([r in rels for r in relation.is_a])]
return self.get_dot_graph(root=roots, graph=graph, relations=relations,
style=style)
get_figsize(graph)
¶
Returns figure size (width, height) in points of figures for the
current pydot graph object graph
.
Source code in ontopy/ontograph.py
def get_figsize(graph):
"""Returns figure size (width, height) in points of figures for the
current pydot graph object `graph`."""
with tempfile.TemporaryDirectory() as tmpdir:
tmpfile = os.path.join(tmpdir, 'graph.svg')
graph.write_svg(tmpfile)
xml = ET.parse(tmpfile)
svg = xml.getroot()
width = svg.attrib['width']
height = svg.attrib['height']
assert width.endswith('pt') # ensure that units are in points
def asfloat(s):
return float(re.match(r'^[\d.]+', s).group())
return asfloat(width), asfloat(height)