def tree_gaussian_kernel(tree, plane='xy', feature='radial_distances', title='', diameter=True, treecol='b', xlims=None, ylims=None, **kwargs): '''Subplot with ph, barcode and tree within spheres ''' from tmd import utils as _utils from matplotlib.collections import LineCollection kwargs['output_path'] = kwargs.get('output_path', None) fig1, ax1 = _view.tree(tree, new_fig=True, subplot=121, plane='xy', title=title, treecolor=treecol, diameter=diameter) feat = getattr(tree, 'get_section_' + feature)() segs = tree.get_segments() def _seg_2d(seg): """2d coordinates required for the plotting of a segment""" horz = _utils.term_dict[plane[0]] vert = _utils.term_dict[plane[1]] horz1 = seg[0][horz] horz2 = seg[1][horz] vert1 = seg[0][vert] vert2 = seg[1][vert] return ((horz1, vert1), (horz2, vert2)) if plane in ['xy', 'yx', 'zx', 'xz', 'yz', 'zy']: ph = _tm.methods.get_persistence_diagram(tree, feature=feature) else: raise Exception('Plane value not recognised') bounds = max(max(ph)) fig1, ax2 = gaussian_kernel(ph, new_fig=False, subplot=122, xlims=xlims, ylims=ylims) _view.common.plt.tight_layout(True) if kwargs['output_path'] is not None: fig = _view.common.save_plot(fig=ax1, **kwargs) return fig1, ax1
def ph_diagram_tree(tree, new_fig=True, plane='xy', output_dir=None, **kwargs): """ Generates a 2d figure (barcode) of the persistent homology of a tree as it has been computed by Topology.get_persistent_homology method. """ if plane in ['xy', 'yx', 'zx', 'xz', 'yz', 'zy']: ph = _tm.methods.get_persistence_diagram(tree, dim=plane) else: raise Exception('Plane value not recognised') bounds = max(max(ph)) for ip, p in enumerate(ph): ph[ip].append(_np.abs(p[0] - p[1])) ph.sort(key=lambda x: x[2]) for ip, p in enumerate(ph): fig, ax = _view.tree(tree, new_fig=new_fig, subplot=121, plane=plane) c1 = _view.common.plt.Circle([tree.x[0], tree.y[0]], p[0], alpha=0.2) c2 = _view.common.plt.Circle([tree.x[0], tree.y[0]], p[1], alpha=0.2) ax.add_patch(c1) # pylint: disable=no-member ax.add_patch(c2) # pylint: disable=no-member fig, ax = _view.common.get_figure(new_fig=False, subplot=122) for ip1, p1 in enumerate(ph): if ip1 != ip: ax.scatter(p1[0], p1[1], c='b') else: ax.scatter(p1[0], p1[1], c='r', s=50) kwargs['title'] = kwargs.get('title', 'P.H. diagram') kwargs['xlabel'] = kwargs.get('xlabel', 'Birth') kwargs['ylabel'] = kwargs.get('ylabel', 'Death') _view.common.plot_style(fig, ax, **kwargs) _view.common.plt.plot([0, bounds], [0, bounds]) if output_dir is not None: kwargs['output_path'] = output_dir kwargs['output_name'] = 'ph_' + '0' * ( 2 - len(str(len(tree.get_bifurcations()) - ip))) + str( len(tree.get_bifurcations()) - ip) + '.png' _view.common.save_plot(fig, **kwargs) if output_dir is not None: kwargs['output_path'] = None kwargs['output_name'] = None
def ph_on_tree(tree, new_fig=True, subplot=False, plane='xy', alpha=0.05, **kwargs): """ Generates a 3d figure of the tree and adds the corresponding spheres that represent important events in the persistent homology diagram (birth and death of components). """ # Initialization of matplotlib figure and axes. fig, ax = _view.tree(tree, new_fig=new_fig, subplot=subplot, plane=plane, **kwargs) if plane in ['xy', 'yx', 'zx', 'xz', 'yz', 'zy']: ph = _tm.methods.get_persistence_diagram(tree, dim=plane) else: raise Exception('Plane value not recognised') for p in ph: c1 = _view.common.plt.Circle([tree.x[0], tree.y[0], tree.z[0]], p[0], alpha=alpha) c2 = _view.common.plt.Circle([tree.x[0], tree.y[0], tree.z[0]], p[1], alpha=alpha) ax.add_patch(c1) # pylint: disable=no-member ax.add_patch(c2) # pylint: disable=no-member return _view.common.plot_style(fig=fig, ax=ax, **kwargs)
def tree_instance(tree, new_fig=True, plane='xy', component_num=1, feature='radial_distances', diameter=True, col='r', treecol='b', **kwargs): '''Subplot with ph, barcode and tree within spheres ''' from tmd import utils as _utils from matplotlib.collections import LineCollection if new_fig: fig1, ax1 = _view.tree(tree, new_fig=new_fig, subplot=121, plane='xy', title='', treecolor=treecol, diameter=diameter) else: fig1, ax1 = _view.common.get_figure(new_fig=new_fig, subplot=121) feat = getattr(tree, 'get_section_' + feature)() segs = tree.get_segments() def _seg_2d(seg): """2d coordinates required for the plotting of a segment""" horz = _utils.term_dict[plane[0]] vert = _utils.term_dict[plane[1]] horz1 = seg[0][horz] horz2 = seg[1][horz] vert1 = seg[0][vert] vert2 = seg[1][vert] return ((horz1, vert1), (horz2, vert2)) if plane in ['xy', 'yx', 'zx', 'xz', 'yz', 'zy']: ph = _tm.methods.get_persistence_diagram(tree, feature=feature) else: raise Exception('Plane value not recognised') bounds = max(max(ph)) if new_fig: fig1, ax2 = barcode(ph, new_fig=False, subplot=222, color=treecol) fig1, ax3 = ph_diagram(ph, new_fig=False, subplot=224, color=treecol) else: fig1, ax2 = _view.common.get_figure(new_fig=new_fig, subplot=222) fig1, ax3 = _view.common.get_figure(new_fig=new_fig, subplot=224) ph = sort_ph(ph) select_section = ph[component_num] ax2.plot(select_section[:-1], [component_num, component_num], color=col, linewidth=2.) ax3.scatter(select_section[0], select_section[1], color=col, s=50.) initial = _np.transpose( tree.get_sections())[_np.where(feat == select_section[0])[0]] all_way = _np.array(tree.get_way_to_root(initial[0][1])) if select_section[1] != -1: final = _np.transpose( tree.get_sections())[_np.where(feat == select_section[1])[0]] until = _np.array(tree.get_way_to_root(final[0][1])) else: until = _np.array(tree.get_way_to_root(0)) between = _np.setxor1d(all_way, until) tmp_segs = _np.array(segs)[between] toplot_segs = [_seg_2d(seg) for seg in tmp_segs] linewidth = [2 * d * 2 for d in _np.array(tree.d)[between]] collection = LineCollection(toplot_segs, color=col, linewidth=linewidth, alpha=1.) ax1.add_collection(collection) _view.common.plt.tight_layout(True) return ax1, collection