Source code for ClearMap.Visualization.Vispy.GraphVisual

# -*- coding: utf-8 -*-
"""
GraphVisual
===========

Module providing Graph visuals for rendering graphs.

Note
----
This module is porviding vispy visuals only. 
See :mod:`PlotGraph3d` module for plotting.
"""
__author__    = 'Christoph Kirst <ckirst@rockefeller.edu>'
__license__   = 'MIT License <http://www.opensource.org/licenses/mit-license.php>'
__copyright__ = 'Copyright (c) 2017 by Christoph Kirst, The Rockefeller University, New York City'


import numpy as np

import vispy.visuals as visuals

import ClearMap.Analysis.Graphs.GraphRendering as gr  
import ClearMap.Visualization.Color as col


###############################################################################
### Graph visuals
###############################################################################

default_color = (0.8, 0.1, 0.1, 1.0);

[docs]class GraphLineVisual(visuals.LineVisual): """Displays a graph in 3d using tube rendering for the edges """ def __init__(self, graph, coordinates = None, color = None, vertex_colors = None, edge_colors = None, width = None, mode = 'gl'): connectivity = graph.edge_connectivity(); if coordinates is None: name = 'coordinates' else: name = coordinates; coordinates = graph.vertex_property(name); if vertex_colors is not None or edge_colors is not None: color = None; if color is None: if edge_colors is None and vertex_colors is None: color = default_color; elif vertex_colors is not None: if isinstance(vertex_colors, np.ndarray) and vertex_colors.ndim == 2: color = vertex_colors; else: color = col.color(vertex_colors, alpha=True); elif edge_colors is not None: if isinstance(edge_colors, np.ndarray) and edge_colors.ndim == 2: #need a vertex pair for every edge if the color is different coordinates = coordinates[connectivity.flatten()]; connectivity = np.arange(coordinates.shape[0]); connectivity = connectivity.reshape((-1,2)); indices = np.arange(len(edge_colors)); indices = np.array([indices, indices]).T.flatten(); color = edge_colors[indices]; else: color = col.color(edge_colors, alpha=True); else: color = col.color(color, alpha=True); if width is None: width = 1; visuals.LineVisual.__init__(self, coordinates, connect=connectivity, color=color, width=width, method=mode)
[docs]class GraphMeshVisual(visuals.mesh.MeshVisual): """Displays a graph in 3d using tube rendering for the edges """ def __init__(self, graph, coordinates = None, radii = None, n_tube_points = 8, default_radius = 1, color = None, vertex_colors = None, edge_colors = None, mode = 'triangles', shading = 'smooth'): if vertex_colors is not None or edge_colors is not None: color = None; if color is None and vertex_colors is None: color = default_color; if graph.has_edge_geometry(): if coordinates is None: name = 'coordinates'; else: name = coordinates; coordinates, indices = graph.edge_geometry(name=name, return_indices=True, as_list=False); #calculate mesh try: if radii is None: name = 'radii'; else: name = radii; radii = graph.edge_geometry(name=name, return_indices=False, as_list=False); except: print('No radii found in the graph, using uniform radii = %r!' % default_radius); radii = default_radius * np.ones(coordinates.shape[0]); else: coordinates = graph.vertex_coordinates(); indices = graph.edge_connectivity().flatten(); coordinates = np.vstack(coordinates[indices]); try: radii = graph.vertex_radii(); radii = radii[indices]; except: print('No radii found in the graph, using uniform radii = %r!' % default_radius); radii = default_radius * np.ones(coordinates.shape[0]); n_edges = graph.n_edges; indices = np.array([2*np.arange(0,n_edges), 2*np.arange(1,n_edges+1)]).T; #print(radii.shape, indices.shape, coordinates.shape) if vertex_colors is not None: connectivity = graph.edge_connectivity(); edge_colors = (vertex_colors[connectivity[:,0]] + vertex_colors[connectivity[:,1]])/2.0; vertices, faces, vertex_colors = gr.mesh_tube_from_coordinates_and_radii(coordinates, radii, indices, n_tube_points=n_tube_points, edge_colors=edge_colors, processes=None); visuals.mesh.MeshVisual.__init__(self, vertices, faces, color=color, vertex_colors=vertex_colors, shading=shading, mode=mode)
############################################################################### ### Tests ############################################################################### def _test(): import numpy as np import vispy import ClearMap.Analysis.Graphs.GraphGt as ggt import ClearMap.Visualization.Vispy.Plot3d as p3d import ClearMap.Visualization.Vispy.GraphVisual as gv #reload(gv) g = ggt.Graph(); g.add_vertex(5); g.add_edge([[0,1],[1,2],[2,3],[3,4],[4,0]]); g.set_vertex_coordinates(20*np.random.rand(5,3)) v = vispy.scene.visuals.create_visual_node(gv.GraphLineVisual) p = v(g, parent=p3d.initialize_view().scene) p3d.center(p) v = vispy.scene.visuals.create_visual_node(gv.GraphMeshVisual) p = v(g, parent=p3d.initialize_view().scene) p3d.center(p)