Source code for mevis._internal.plotting

from collections.abc import Callable as _Callable

import gravis as _gv
import networkx as _nx
from opencog.atomspace import Atom as _Atom
from opencog.type_constructors import AtomSpace as _AtomSpace

from .args import check_arg as _check_arg
from .conversion import convert as _convert
from .filtering import filter as _filter
from .layouting import LAYOUT_METHODS as _LAYOUT_METHODS
from .layouting import layout as _layout


[docs]def plot(data, backend='vis', layout_method=None, layout_scale_x=1.0, layout_scale_y=1.0, layout_mirror_x=False, layout_mirror_y=True, layout_center_x=True, layout_center_y=True, filter_target=None, filter_context='atom', filter_mode='include', graph_annotated=True, graph_directed=True, node_label=None, node_color=None, node_opacity=None, node_size=None, node_shape=None, node_border_color=None, node_border_size=None, node_label_color=None, node_label_size=None, node_hover=None, node_click=None, node_image=None, node_properties=None, edge_label=None, edge_color=None, edge_opacity=None, edge_size=None, edge_label_color=None, edge_label_size=None, edge_hover=None, edge_click=None, **kwargs): """Create a graph visualization of a given AtomSpace, list of Atoms or NetworkX graph. Parameters ---------- data : Atomspace, list of Atoms, NetworkX Graph, NetworkX DiGraph The input data that shall be visualized. If it is already a NetworkX Graph or NetworkX DiGraph, no conversion, layouting and filtering steps are performed, which means that most arguments have no effect. backend : str Library used for the graph visualization. Possible values: - ``"d3"``: Uses `d3.js <https://d3js.org/>`__ to generate a 2d plot based on the `HTML SVG element <https://developer.mozilla.org/en-US/docs/Web/SVG/Element/svg>`__, which is vector graphics that can be exported as SVG, PNG or JPG. - ``"vis"``: Uses `vis.js <https://visjs.org/>`__ to generate a 2d plot based on the `HTML Canvas element <https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API>`__, which is raster graphics that can be exported as PNG or JPG. - ``"three"``: Uses `three.js <https://threejs.org/>`__ to generate a 3d plot based on `HTML WebGL element <https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API>`__, which is raster graphics that can be exported as PNG or JPG. filter_[...] See documentation of the :func:`filter` function. graph_[...], node_[...], edge_[...] See documentation of the :func:`convert` function. layout_[...] See documentation of the :func:`layout` function. kwargs Other keyword arguments are forwarded to the plotting method. See documentation of `gravis <https://robert-haas.github.io/gravis-docs/>`__. Various aspects of the graph visualizations can be changed interactively by a user in the HTML menus, but often it is desirable to set suitable initial values, e.g. ``edge_curvature=0.2`` for curved instead of straight edges. Returns ------- fig : `Figure <https://robert-haas.github.io/gravis-docs/rst/api/figure.html>`__ A figure object from gravis that can be used for displaying or exporting the plot. Note ---- **Pre-processing steps** can be triggered by providing values for the arguments ``filter_target`` or ``layout_method`` and modified by providing values for arguments like ``node_color`` and ``node_size``. 1. **Filter**: Reduce the AtomSpace to a list of relevant Atoms. 2. **Convert**: Transform the AtomSpace to a NetworkX graph and add annotations to its nodes and edges. By providing arguments like ``node_size`` it is possible to translate information such as truth values into visual properties such as node size, color or shape. 3. **Layout**: Calculate x and y coordinates to better recognize structures in the AtomSpace such as hierarchies and clusters. These steps are implemented by the functions :func:`filter`, :func:`convert` and :func:`layout`. They are called implicitely by this plotting function with default arguments. Alternatively, they can be called explicitly by a user on an AtomSpace for finer control. The result can then be fed into this plotting function. """ # Argument processing _check_arg(data, 'data', (_AtomSpace, list, _nx.Graph, _nx.DiGraph)) _check_arg(backend, 'backend', str, ['d3', 'vis', 'three']) # layout _check_arg(layout_method, 'layout_method', str, _LAYOUT_METHODS, allow_none=True) _check_arg(layout_scale_x, 'layout_scale_x', (int, float)) _check_arg(layout_scale_x, 'layout_scale_y', (int, float)) _check_arg(layout_mirror_x, 'layout_mirror_x', bool) _check_arg(layout_mirror_y, 'layout_mirror_y', bool) _check_arg(layout_center_x, 'layout_center_x', bool) _check_arg(layout_center_y, 'layout_center_y', bool) # filter _check_arg( filter_target, 'filter_target', (str, int, list, _Callable, _Atom), allow_none=True) _check_arg(filter_context, 'filter_context', (str, tuple)) _check_arg(filter_mode, 'filter_mode', str, ['include', 'exclude']) # convert: arguments have exactly the same name and thus are checked in the convert function # Preparing the graph or AtomSpace if isinstance(data, (_nx.Graph, _nx.DiGraph)): graph = data else: # Optional: Filtering of AtomSpace if filter_target is None: atoms = data else: atoms = _filter(data, filter_target, filter_context, filter_mode) # Conversion of AtomSpace to graph graph = _convert( atoms, graph_annotated, graph_directed, node_label, node_color, node_opacity, node_size, node_shape, node_border_color, node_border_size, node_label_color, node_label_size, node_hover, node_click, node_image, node_properties, edge_label, edge_color, edge_opacity, edge_size, edge_label_color, edge_label_size, edge_hover, edge_click) # Optional: Layout of graph if layout_method is not None: graph = _layout( graph, layout_method, layout_scale_x, layout_scale_y, layout_mirror_x, layout_mirror_y, layout_center_x, layout_center_y) # Setting some defaults for plotting kwargs['node_label_data_source'] = kwargs.get('node_label_data_source', 'label') kwargs['edge_label_data_source'] = kwargs.get('edge_label_data_source', 'label') kwargs['show_edge_label'] = kwargs.get('show_edge_label', edge_label is not None) # Plotting if backend == 'd3': fig = _gv.d3(graph, **kwargs) elif backend == 'vis': fig = _gv.vis(graph, **kwargs) elif backend == 'three': fig = _gv.three(graph, **kwargs) return fig