From 6c168fd66648b1472ca4f2c3e97c68a01b8942d4 Mon Sep 17 00:00:00 2001
From: "Francesca L. Bleken" <48128015+francescalb@users.noreply.github.com>
Date: Mon, 23 May 2022 11:35:34 +0200
Subject: [PATCH] cytoscapegraph fails with missing edge labels (#414)
* visualisation with cytoscapewidget improved with documentation.
Graph given as parameter should be generated with edgelabel = True
(this was default previously).
This has been documented, and the overall docuementation improved.
Error on providing this is returned as an EMMOntoPyException with explanation.
Adding the parameter force will make a graph with incorrect edges and an error stating this.
---
.../jupyter-visualization/emmographs.ipynb | 290 ++++++++----------
ontopy/graph.py | 53 +++-
2 files changed, 175 insertions(+), 168 deletions(-)
diff --git a/examples/jupyter-visualization/emmographs.ipynb b/examples/jupyter-visualization/emmographs.ipynb
index 15b98d48e..1bd33ad4c 100644
--- a/examples/jupyter-visualization/emmographs.ipynb
+++ b/examples/jupyter-visualization/emmographs.ipynb
@@ -3,6 +3,9 @@
{
"cell_type": "code",
"execution_count": 1,
+ "id": "a01799c2",
+ "metadata": {},
+ "outputs": [],
"source": [
"from ontopy import get_ontology\n",
"#import networkx as nx\n",
@@ -11,108 +14,93 @@
"#import pydotplus\n",
"#import ipycytoscape\n",
"#import ipywidgets as widgets"
- ],
- "outputs": [],
- "metadata": {}
+ ]
},
{
"cell_type": "code",
"execution_count": 2,
+ "id": "f9917c47",
+ "metadata": {},
+ "outputs": [],
"source": [
"onto = get_ontology('emmo-inferred').load()"
- ],
- "outputs": [],
- "metadata": {}
+ ]
},
{
"cell_type": "code",
- "execution_count": 3,
+ "execution_count": 6,
+ "id": "aead21d4",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/svg+xml": "\n\n\n\n\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 6,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
"leafs = set()\n",
"for s in onto.Perspective.subclasses():\n",
" leafs.update(s.subclasses())\n",
- "graph = OntoGraph(onto, onto.Perspective, leafs=leafs, parents=1)\n",
+ "graph = OntoGraph(onto, onto.Perspective, leafs=leafs, parents=1, edgelabels=True)\n",
"\n",
"graph.dot\n",
"#graph = OntoGraph(onto, onto.isA, leafs=('Physical',))\n",
"#digraph = graph.dot\n",
"#graph.get_edges()\n",
"#[print(g) for g in G.nodes()]"
- ],
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "id": "02bbc250",
+ "metadata": {},
"outputs": [
{
- "output_type": "execute_result",
"data": {
- "image/svg+xml": "\n\n\n\n\n",
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "d13ebc3304184eafa0583d926f64bd79",
+ "version_major": 2,
+ "version_minor": 0
+ },
"text/plain": [
- ""
+ "GridspecLayout(children=(CytoscapeWidget(cytoscape_layout={'name': 'cola'}, cytoscape_style=[{'selector': 'nod…"
]
},
"metadata": {},
- "execution_count": 3
+ "output_type": "display_data"
}
],
- "metadata": {}
- },
- {
- "cell_type": "code",
- "execution_count": 4,
"source": [
"cytograph = cytoscapegraph(graph, onto=onto, infobox='right')\n",
"display(cytograph)"
- ],
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "bd75e3c2",
+ "metadata": {},
"outputs": [
{
- "output_type": "display_data",
"data": {
- "application/vnd.jupyter.widget-view+json": {
- "model_id": "c8ca13f486a742ae909445f5371ab5de",
- "version_major": 2,
- "version_minor": 0
- },
+ "image/svg+xml": "\n\n\n\n\n",
"text/plain": [
- "GridspecLayout(children=(CytoscapeWidget(cytoscape_layout={'name': 'cola'}, cytoscape_style=[{'selector': 'nod…"
+ ""
]
},
- "metadata": {}
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
}
],
- "metadata": {}
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "source": [],
- "outputs": [],
- "metadata": {}
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "source": [],
- "outputs": [],
- "metadata": {}
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "source": [],
- "outputs": [],
- "metadata": {
- "scrolled": true,
- "tags": []
- }
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "source": [],
- "outputs": [],
- "metadata": {}
- },
- {
- "cell_type": "code",
- "execution_count": 5,
"source": [
"leafs = {onto.Interpreter, onto.Conventional, onto.Icon, onto.Observation,\n",
" onto.Object}\n",
@@ -123,35 +111,18 @@
"g = OntoGraph(onto)\n",
"g.add_entities(semiotic, relations='all', edgelabels=True)\n",
"g.dot"
- ],
- "outputs": [
- {
- "output_type": "execute_result",
- "data": {
- "image/svg+xml": "\n\n\n\n\n",
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "execution_count": 5
- }
- ],
- "metadata": {}
+ ]
},
{
"cell_type": "code",
- "execution_count": 6,
- "source": [
- "cytograph2 = cytoscapegraph(g, onto=onto, infobox='right')\n",
- "display(cytograph2)"
- ],
+ "execution_count": 9,
+ "id": "c20bc4fb",
+ "metadata": {},
"outputs": [
{
- "output_type": "display_data",
"data": {
"application/vnd.jupyter.widget-view+json": {
- "model_id": "11003b8f7503456cbcc2c8147915b886",
+ "model_id": "55e3c07a21b746b6988b5cd99328a69e",
"version_major": 2,
"version_minor": 0
},
@@ -159,183 +130,182 @@
"GridspecLayout(children=(CytoscapeWidget(cytoscape_layout={'name': 'cola'}, cytoscape_style=[{'selector': 'nod…"
]
},
- "metadata": {}
+ "metadata": {},
+ "output_type": "display_data"
}
],
- "metadata": {}
+ "source": [
+ "cytograph2 = cytoscapegraph(g, onto=onto, infobox='right')\n",
+ "display(cytograph2)"
+ ]
},
{
"cell_type": "code",
- "execution_count": 7,
- "source": [
- "g.dot.source"
- ],
- "outputs": [
- {
- "output_type": "execute_result",
- "data": {
- "text/plain": [
- "'digraph {\\n\\tgraph [fontsize=8 rankdir=BT]\\n\\tSemiotic [label=Semiotic URL=\"http://emmo.info/emmo/middle/semiotics#EMMO_b803f122_4acb_4064_9d71_c1e5fd091fc9\" fillcolor=\"#ffc880\" style=filled]\\n\\tSign [label=Sign URL=\"http://emmo.info/emmo/middle/semiotics#EMMO_b21a56ed_f969_4612_a6ec_cb7766f7f31d\" fillcolor=\"#ffc880\" style=filled]\\n\\tParticipant [label=Participant URL=\"http://emmo.info/emmo/middle/holistic#EMMO_49804605_c0fe_4538_abda_f70ba1dc8a5d\" fillcolor=\"#ffffcc\" style=filled]\\n\\tProcess [label=Process URL=\"http://emmo.info/emmo/middle/holistic#EMMO_43e9a05d_98af_41b4_92f6_00f79a09bfce\" fillcolor=\"#ffffcc\" style=filled]\\n\\tIndex [label=Index URL=\"http://emmo.info/emmo/middle/semiotics#EMMO_0cd58641_824c_4851_907f_f4c3be76630c\" fillcolor=\"#ffffcc\" style=filled]\\n\\tHolistic [label=Holistic URL=\"http://emmo.info/emmo/middle/holistic#EMMO_0277f24a_ea7f_4917_81b7_fb0406c8fc62\" fillcolor=\"#ffc880\" style=filled]\\n\\tSemiosis [label=Semiosis URL=\"http://emmo.info/emmo/middle/semiotics#EMMO_008fd3b2_4013_451f_8827_52bceab11841\" fillcolor=\"#ffffcc\" style=filled]\\n\\tInterpreter [label=Interpreter URL=\"http://emmo.info/emmo/middle/semiotics#EMMO_0527413c_b286_4e9c_b2d0_03fb2a038dee\" fillcolor=\"#ffffcc\" style=filled]\\n\\tConventional [label=Conventional URL=\"http://emmo.info/emmo/middle/semiotics#EMMO_35d2e130_6e01_41ed_94f7_00b333d46cf9\" fillcolor=\"#ffffcc\" style=filled]\\n\\tIcon [label=Icon URL=\"http://emmo.info/emmo/middle/semiotics#EMMO_d7788d1a_020d_4c78_85a1_13563fcec168\" fillcolor=\"#ffffcc\" style=filled]\\n\\tObject [label=Object URL=\"http://emmo.info/emmo/middle/semiotics#EMMO_6f5af708_f825_4feb_a0d1_a8d813d3022b\" fillcolor=\"#ffffcc\" style=filled]\\n\\tInterpretant [label=Interpretant URL=\"http://emmo.info/emmo/middle/semiotics#EMMO_054af807_85cd_4a13_8eba_119dfdaaf38b\" fillcolor=\"#ffffcc\" style=filled]\\n\\tObservation [label=Observation URL=\"http://emmo.info/emmo/middle/properties#EMMO_10a5fd39_06aa_4648_9e70_f962a9cb2069\" fillcolor=\"#ffffcc\" style=filled]\\n\\tSign -> Semiotic [label=isA arrowhead=empty]\\n\\tObject -> Semiotic [label=isA arrowhead=empty]\\n\\tSemiosis -> Process [label=isA arrowhead=empty]\\n\\tSemiosis -> Object [label=\"hasProperParticipant some\" color=red constraint=false style=dashed]\\n\\tSemiosis -> Sign [label=\"hasProperParticipant some\" color=red constraint=false style=dashed]\\n\\tSemiosis -> Interpreter [label=\"hasProperParticipant some\" color=red constraint=false style=dashed]\\n\\tInterpreter -> Semiotic [label=isA arrowhead=empty]\\n\\tInterpreter -> Interpretant [label=\"hasSpatialPart some\" color=darkgreen constraint=false]\\n\\tParticipant -> Holistic [label=isA arrowhead=empty]\\n\\tParticipant -> Process [label=\"Inverse(hasParticipant) some\" arrowhead=inv color=red constraint=false]\\n\\tInterpretant -> Sign [label=isA arrowhead=empty]\\n\\tSemiotic -> Participant [label=isA arrowhead=empty]\\n\\tSemiotic -> Semiosis [label=\"Inverse(hasProperParticipant) some\" arrowhead=inv color=red constraint=false style=dashed]\\n\\tIndex -> Sign [label=isA arrowhead=empty]\\n\\tProcess -> Holistic [label=isA arrowhead=empty]\\n\\tProcess -> Participant [label=\"hasParticipant some\" color=red constraint=false]\\n\\tObservation -> Semiosis [label=isA arrowhead=empty]\\n\\tIcon -> Sign [label=isA arrowhead=empty]\\n\\tConventional -> Sign [label=isA arrowhead=empty]\\n}'"
- ]
- },
- "metadata": {},
- "execution_count": 7
- }
- ],
- "metadata": {}
+ "execution_count": null,
+ "id": "ccd9c9a2",
+ "metadata": {},
+ "outputs": [],
+ "source": []
},
{
"cell_type": "code",
- "execution_count": 8,
- "source": [
- "onto.Atom.iri"
- ],
- "outputs": [
- {
- "output_type": "execute_result",
- "data": {
- "text/plain": [
- "'http://emmo.info/emmo/middle/materials#EMMO_eb77076b_a104_42ac_a065_798b2d2809ad'"
- ]
- },
- "metadata": {},
- "execution_count": 8
- }
- ],
- "metadata": {}
+ "execution_count": null,
+ "id": "91a47699",
+ "metadata": {},
+ "outputs": [],
+ "source": []
},
{
"cell_type": "code",
"execution_count": null,
- "source": [],
+ "id": "0134c7bc",
+ "metadata": {},
"outputs": [],
- "metadata": {}
+ "source": []
},
{
"cell_type": "code",
"execution_count": null,
- "source": [],
+ "id": "99bf716e",
+ "metadata": {},
"outputs": [],
- "metadata": {}
+ "source": []
},
{
"cell_type": "code",
"execution_count": null,
- "source": [],
+ "id": "c5f3c683",
+ "metadata": {},
"outputs": [],
- "metadata": {}
+ "source": []
},
{
"cell_type": "raw",
- "source": [],
- "metadata": {}
+ "id": "40ebb5bc",
+ "metadata": {},
+ "source": []
},
{
"cell_type": "code",
"execution_count": null,
- "source": [],
+ "id": "2e398e4a",
+ "metadata": {},
"outputs": [],
- "metadata": {}
+ "source": []
},
{
"cell_type": "code",
"execution_count": null,
- "source": [],
+ "id": "5f6f7caf",
+ "metadata": {},
"outputs": [],
- "metadata": {}
+ "source": []
},
{
"cell_type": "code",
"execution_count": null,
- "source": [],
+ "id": "a3352c37",
+ "metadata": {},
"outputs": [],
- "metadata": {}
+ "source": []
},
{
"cell_type": "code",
"execution_count": null,
- "source": [],
+ "id": "c536b411",
+ "metadata": {},
"outputs": [],
- "metadata": {}
+ "source": []
},
{
"cell_type": "code",
"execution_count": null,
- "source": [],
+ "id": "3253b09c",
+ "metadata": {},
"outputs": [],
- "metadata": {}
+ "source": []
},
{
"cell_type": "code",
"execution_count": null,
- "source": [],
+ "id": "7c170bef",
+ "metadata": {},
"outputs": [],
- "metadata": {}
+ "source": []
},
{
"cell_type": "code",
"execution_count": null,
- "source": [],
+ "id": "c463b3ba",
+ "metadata": {},
"outputs": [],
- "metadata": {}
+ "source": []
},
{
"cell_type": "code",
"execution_count": null,
- "source": [],
+ "id": "b5834885",
+ "metadata": {},
"outputs": [],
- "metadata": {}
+ "source": []
},
{
"cell_type": "code",
"execution_count": null,
- "source": [],
+ "id": "74d14d13",
+ "metadata": {},
"outputs": [],
- "metadata": {}
+ "source": []
},
{
"cell_type": "code",
"execution_count": null,
- "source": [],
+ "id": "bb7bbb02",
+ "metadata": {},
"outputs": [],
- "metadata": {}
+ "source": []
},
{
"cell_type": "code",
"execution_count": null,
- "source": [],
+ "id": "b067143a",
+ "metadata": {},
"outputs": [],
- "metadata": {}
+ "source": []
},
{
"cell_type": "code",
"execution_count": null,
+ "id": "16ee6113",
+ "metadata": {},
+ "outputs": [],
"source": [
"\n"
- ],
- "outputs": [],
- "metadata": {}
+ ]
},
{
"cell_type": "code",
"execution_count": null,
- "source": [],
+ "id": "01873024",
+ "metadata": {},
"outputs": [],
- "metadata": {}
+ "source": []
},
{
"cell_type": "code",
"execution_count": null,
- "source": [],
+ "id": "9bd1dd33",
+ "metadata": {},
"outputs": [],
- "metadata": {}
+ "source": []
},
{
"cell_type": "code",
"execution_count": null,
- "source": [],
+ "id": "81865350",
+ "metadata": {},
"outputs": [],
- "metadata": {}
+ "source": []
}
],
"metadata": {
diff --git a/ontopy/graph.py b/ontopy/graph.py
index a9135fc98..30dc14219 100644
--- a/ontopy/graph.py
+++ b/ontopy/graph.py
@@ -6,12 +6,19 @@
import os
import re
import tempfile
+import warnings
+from typing import Optional, TYPE_CHECKING
import defusedxml.ElementTree as ET
-
import owlready2
import graphviz
from ontopy.utils import asstring, get_label
+from ontopy.ontology import Ontology
+from ontopy.utils import EMMOntoPyException
+
+if TYPE_CHECKING:
+ from ipywidgets.widgets.widget_templates import GridspecLayout
+
typenames = (
owlready2.class_construct._restriction_type_2_label # pylint: disable=protected-access
@@ -1046,11 +1053,26 @@ def get_deps(iri, excl=None):
def cytoscapegraph(
- graph, onto=None, infobox=None
-): # pylint: disable=too-many-locals,too-many-statements
+ graph: OntoGraph,
+ onto: Optional[Ontology] = None,
+ infobox: str = None,
+ force: bool = False,
+) -> "GridspecLayout":
+ # pylint: disable=too-many-locals,too-many-statements
"""Returns and instance of icytoscape-figure for an
- instance Graph of OntoGraph, the accomanying ontology
- is required for mouse actions"""
+ instance Graph of OntoGraph, the accompanying ontology
+ is required for mouse actions.
+ Args:
+ graph: graph generated with OntoGraph with edgelabels=True.
+ onto: ontology to be used for mouse actions.
+ infobox: "left" or "right". Placement of infbox with
+ respect to graph.
+ force: force generate graph withour correct edgelabels.
+ Returns:
+ cytoscapewidget with graph and infobox to be visualized
+ in jupyter lab.
+
+ """
# pylint: disable=import-error,import-outside-toplevel
from ipywidgets import Output, VBox, GridspecLayout
from IPython.display import display, Image
@@ -1069,9 +1091,24 @@ def cytoscapegraph(
data = cytoscape_data(pydot_graph)["elements"]
for datum in data["edges"]:
- datum["data"]["label"] = (
- datum["data"]["label"].rsplit(" ", 1)[0].lstrip('"')
- )
+ try:
+ datum["data"]["label"] = (
+ datum["data"]["label"].rsplit(" ", 1)[0].lstrip('"')
+ )
+ except KeyError as err:
+ if not force:
+ raise EMMOntoPyException(
+ "Edge label is not defined. Are you sure that the OntoGraph"
+ "instance you provided was generated with "
+ "´edgelabels=True´?"
+ ) from err
+ warnings.warn(
+ "ARROWS WILL NOT BE DISPLAYED CORRECTLY. "
+ "Edge label is not defined. Are you sure that the OntoGraph "
+ "instance you provided was generated with ´edgelabels=True´?"
+ )
+ datum["data"]["label"] = ""
+
lab = datum["data"]["label"].replace("Inverse(", "").rstrip(")")
try:
datum["data"]["colour"] = colours[lab]