Skip to content

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)
Back to top