Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More general subgraph visualization utility #22

Open
dhimmel opened this issue Mar 29, 2022 · 0 comments
Open

More general subgraph visualization utility #22

dhimmel opened this issue Mar 29, 2022 · 0 comments

Comments

@dhimmel
Copy link
Member

dhimmel commented Mar 29, 2022

The current visualization function create_similarity_graphviz is specific to visualizing the similarity between two nodes.

It's common that the user has a known subset of nodes for which they'd like to visualize the subgraph. Some flexibility is needed to allow users to pick how they'd like to label nodes and to apply additional styling. So proposing utility functions to help create subgraphs for graphviz visualizations.

Some existing code below that might be helpful

Expand for code
# code used to create figures at https://github.com/EBISPOT/efo/issues/926#issuecomment-760366239
from nxontology import NXOntology
from typing import Iterable
from nxontology.ontology import Node
from nxontology.viz import get_hex_color
from networkx.drawing.nx_agraph import to_agraph
from pygraphviz.agraph import AGraph
from IPython.display import Image

def create_subgraph_for_graphviz(
    nxo: NXOntology,
    nodes: Iterable[Node],
) -> "NXOntology":
    nodes = set(nodes)
    # independent shallow copy: creates new independent attribute dicts
    subgraph = nxo.graph.subgraph(nodes).copy()
    # node labels and fill/font colors
    for node, data in subgraph.nodes(data=True):
        info = nxo.node_info(node)
        if info.label:
            data["label"] = info.name
        if info.identifier:
            data["tooltip"] = info.identifier
        if info.url:
            data["URL"] = info.url
    return subgraph

def create_graphviz(
    nxo: NXOntology,
    nodes: Iterable[Node],
    outline_nodes: Iterable[Node],
    keyword: str,
) -> "AGraph":
    nodes = set(nodes)
    outline_nodes = set(outline_nodes)
    subgraph = create_subgraph_for_graphviz(nxo, nodes)
    for node, data in subgraph.nodes(data=True):
        data["style"] = "filled"
        info = nxo.node_info(node)
        data["label"] = (
            f"<{info.name}<br/>"
            '<font point-size="9">'
            f"{info.n_descendants:,} descendants · IC<sub>res</sub> {info.intrinsic_ic_scaled:.2f}"
            "</font>>"
        )
        scaled_ic = info.intrinsic_ic_scaled
        data["fillcolor"] = get_hex_color(scaled_ic)
        data["fontcolor"] = "#ffffff" if scaled_ic > 0.7 else "#000000"
    # node styles
    for node in nodes - outline_nodes:
        subgraph.nodes[node]["penwidth"] = 1.0
    for node in nodes & outline_nodes:
        subgraph.nodes[node]["penwidth"] = 4.0
        subgraph.nodes[node]["color"] = "#b400b4"
        subgraph.nodes[node]["style"] += ",solid"
    # title
    subgraph.graph["label"] = f"Nodes {keyword} by EFO-OTAR (purple online) and their ancestors"
    subgraph.graph["labelloc"] = "t"
    # raster resolution
    subgraph.graph["dpi"] = 125
    gviz = to_agraph(subgraph)
    gviz.layout("dot")
    return gviz

# elsewhere have found wrapped names in labels is helpful
import textwrap
name_wrapped = "<br/>".join(textwrap.wrap(info.name, width=10, break_long_words=False))

# and finally to plot in a Jupyter notebook
Image(gviz.draw(format="png"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant