def plot(ax, intervals, dim=0, gtype='barcode', xlabel=None, verbose=0): """ Plot the Persistent Homology. Input: gtype - string. 'barcode', plot barcode graph. 'diagram', plot persistence diagram. """ if gtype == 'barcode': y = [i + 1 for i in range(len(intervals[dim]))] x = np.array(intervals[dim]) # if dim equal 0, modified the inf if dim == 0: x[x.shape[0] - 1, x.shape[1] - 1] = x[x.shape[0] - 2, x.shape[1] - 1] + 0.1 out = ax.hlines(y, x[:, 0], x[:, 1], color='b', lw=1) if xlabel: ax.set_xlabel(xlabel) else: ax.set_xlabel('persistent time') ax.set_ylabel('dim-' + str(dim)) return out elif gtype == 'diagram': persim.plot_diagrams(ax=ax, diagrams=intervals)
def PDView(pd,cond,bmin=-2100,bmax=1200,zmin=0,zmax=9999,save_fn=None,size=3): import persim import matplotlib.colors as mcolors bluea = (mcolors.to_rgb("tab:blue") + (0.01,),) orangea = (mcolors.to_rgb("tab:orange") + (0.01,),) greena = (mcolors.to_rgb("tab:green") + (0.01,),) plt.figure(figsize=(24,20)) # select cycles to plot ppd = [pd[ (pd[:,0]==d)*(zmin<=pd[:,5])*(pd[:,5]<=zmax),1:3] for d in range(3)] line_style=['-','--']*len(cond) for i,f in enumerate(cond): ax = plt.subplot(1,len(cond),i+1) persim.plot_diagrams(ppd[f['dim']],ax=ax,xy_range=[bmin,bmax,bmin,bmax],legend=True, size=size, labels=['$H_{}$'.format(f['dim'])]) ax.plot([f['b0'],f['b1']], [f['b0']+f['l0'],f['b1']+f['l0']], line_style[i], c="r") ax.plot([f['b0'],f['b0']], [f['b0']+f['l0'],min(bmax-100,f['b0']+f['l1'])], line_style[i], c="r") ax.plot([f['b1'],f['b1']], [f['b1']+f['l0'],min(bmax-100,f['b1']+f['l1'])], line_style[i], c="r") ax.plot([f['b0'],f['b1']], [min(bmax-100,f['b0']+f['l1']),min(bmax-100,f['b1']+f['l1'])], line_style[i], c="r") if save_fn: plt.savefig(save_fn) plt.show()
def test_plot_only(self): diagrams = [ np.array([[0, 1], [1, 1], [2, 4], [3, 5]]), np.array([[0.5, 3], [2, 4], [4, 5], [10, 15]]) ] f, ax = plt.subplots() plot_diagrams(diagrams, legend=False, show=False, plot_only=[1])
def vec_dgm_by_per_images(dgm, birth_range=None, pers_range=None, max_death=None, pixel_size=None, weight=pimgs.weighting_fxns.persistence, weight_params=None, kernel=pimgs.kernels.bvncdf, kernel_params=None, skew=True, do_plot=False): """ Generates a flattened persistence image feature vector from a persistence diagram subject to the specified hyperparameters :param dgm: (N,2) numpy array encoding a persistence diagram :param birth_range: tuple specifying lower and upper birth value of the persistence image :param pers_range: tuple specifying lower and upper persistence value of the persistence image :param pixel_size: size of square pixel :param weight: function to weight the birth-persistence plane :param weight_params: arguments needed to specify the weight function :param kernel: cumulative distribution function of kernel :param kernel_params: arguments needed to specify the kernel (cumulative distribution) function :param skew: boolean flag indicating if diagram needs to be converted to birth-persistence coordinates (default: True) :return: flattened persistence image in row-major (C-style) order """ dgm = np.copy(dgm) # setup the imager object with specified parameters imgr = pimgs.PersistenceImager(birth_range=birth_range, pers_range=pers_range, pixel_size=pixel_size, weight=weight, weight_params=weight_params, kernel=kernel, kernel_params=kernel_params) # generate and return the persistence image img = imgr.transform(dgm, skew=skew) if max_death: J, I = np.meshgrid(imgr._bpnts[0:-1], imgr._ppnts[0:-1]) img = img.T img[J + I > max_death] = 0 if do_plot: plt.clf() plt.subplot(121) plot_diagrams(dgm, labels=['dgm']) plt.subplot(122) plt.imshow(img, extent=(birth_range[0], birth_range[1], pers_range[0], pers_range[1]), cmap='magma_r', interpolation='none') plt.gca().invert_yaxis() plt.savefig( "n%.3g_sigma%.3g_pix%.3g.png" % (weight_params['n'], kernel_params['sigma'], pixel_size), bbox_inches='tight') return img.flatten(order='C')
def test_infty(self): diagrams = [ np.array([[0, np.inf], [1, 1], [2, 4], [3, 5]]), np.array([[0.5, 3], [2, 4], [4, 5], [10, 15]]) ] f, ax = plt.subplots() plot_diagrams(diagrams, legend=True, show=False)
def test_default_label(self): diagrams = [ np.array([[0, 1], [1, 1], [2, 4], [3, 5]]), np.array([[0.5, 3], [2, 4], [4, 5], [10, 15]]) ] f, ax = plt.subplots() plot_diagrams(diagrams, show=False) assert ax.get_ylabel() == 'Death' assert ax.get_xlabel() == 'Birth'
def test_default_square(self): diagrams = [ np.array([[0, 1], [1, 1], [2, 4], [3, 5]]), np.array([[0.5, 3], [2, 4], [4, 5], [10, 15]]) ] f, ax = plt.subplots() plot_diagrams(diagrams, show=False) diagonal = ax.lines[0].get_xydata() assert diagonal[0, 0] == diagonal[0, 1] assert diagonal[1, 0] == diagonal[1, 1]
def printPHDiagram(data: np.array, id: str): ''' Bundles the functions used to calculate a PH diagram from a dataset. ''' diagrams = ripser(data)['dgms'] plot_diagrams(diagrams, title="Persistence diagram, #" + id, show=False) plt.savefig("persistent_homology_" + id + ".png") data = pd.DataFrame(plt.gca().get_lines().get_xydata()) data.to_csv("ph_" + id + ".csv") return
def tda_to_html(data, show=False, plot_only=[0, 1, 2], max_dim=2): topo = ripser(data, max_dim=2) html = HTML_HEADER html += '<TABLE>\n' html += ' <tr>\n <th>Parameter</th>\n <th>Value</th>\n </tr>\n' for k in 'cocycles num_edges r_cover'.split(): html += f' <tr>\n <td>{k}</td>\n <td>{topo[k]}</td>\n </tr>\n' html += '</TABLE>\n' persim.plot_diagrams(topo['dgms'], show=show, plot_only=plot_only or None) html += fig_to_html() topo['html'] = html return topo
def generate(val = None): plt.clf() global dgms, sld_resolution, sld_spread, bgen, old_resolution, old_spread, bgennoise N_noise = 150 N_circle1 = 0 #200 N_circle2 = 150 N = N_noise + N_circle1 + N_circle2 if val != None: data = 150 * np.random.random((N,2)) else: data = np.concatenate([150 * np.random.random((N_noise,2)), #np.random.randint(10,100) + 10 * datasets.make_circles(n_samples=N_circle1, factor=0.99)[0], np.random.randint(10,100) + 20 * datasets.make_circles(n_samples=N_circle2, factor=0.99)[0]]) if len(argv) > 1: data = np.genfromtxt(argv[1], delimiter = ",") dgms = ripser(data)["dgms"] plt.subplot(231) plt.scatter(data[:,0], data[:,1], s=4) plt.title("Scatter plot N = " + str(N)) plt.subplot(232) plot_diagrams(dgms, legend=False, show=False, lifetime=True) plt.title("Persistence diagram\nof $H_0$ and $H_1$") #to remove the point at infinity dgms[0] = dgms[0][0:N-1] if not first: old_resolution = sld_resolution.val old_spread = sld_spread.val ax_spread = plt.axes([0.1, 0.2, 0.8, 0.05]) sld_spread = Slider(ax_spread, "Spread", 0.1, 2, valinit=old_spread, valstep=0.1) ax_resolution = plt.axes([0.1, 0.1, 0.8, 0.05]) sld_resolution = Slider(ax_resolution, "Resolution", 10, 100, valinit=old_resolution, valstep=10) ax_gen = plt.axes([0.8, 0.01, 0.1, 0.075]) bgen = Button(ax_gen, 'Generate Circles') ax_gen_noise = plt.axes([0.6, 0.01, 0.1, 0.075]) bgennoise = Button(ax_gen_noise, 'Generate Noise') sld_spread.on_changed(calculatePI) sld_resolution.on_changed(calculatePI) bgen.on_clicked(lambda x : generate(None)) bgennoise.on_clicked(lambda x : generate(1)) calculatePI() plt.show()
def test_set_title(self): diagrams = [ np.array([[0, 1], [1, 1], [2, 4], [3, 5]]), np.array([[0.5, 3], [2, 4], [4, 5], [10, 15]]) ] f, ax = plt.subplots() plot_diagrams(diagrams, title='my title', show=False) assert ax.get_title() == 'my title' f, ax = plt.subplots() plot_diagrams(diagrams, show=False) assert ax.get_title() == ''
def test_lifetime(self): diagrams = [ np.array([[0, 1], [1, 1], [2, 4], [3, 5]]), np.array([[0.5, 3], [2, 4], [4, 5], [10, 15]]) ] f, ax = plt.subplots() plot_diagrams(diagrams, lifetime=True, show=False) assert ax.get_ylabel() == 'Lifetime' assert ax.get_xlabel() == 'Birth' line = ax.get_lines()[0] np.testing.assert_array_equal(line.get_ydata(), [0, 0])
def test_legend_false(self): diagrams = [ np.array([[0, 1], [1, 1], [2, 4], [3, 5]]), np.array([[0.5, 3], [2, 4], [4, 5], [10, 15]]) ] f, ax = plt.subplots() plot_diagrams(diagrams, legend=False, show=False) legend = [ child for child in ax.get_children() if child.__class__.__name__ == "Legend" ] assert len(legend) == 0
def plot_persistence_diagram(persistence, output): """Plot a persistence diagram. :param ripser.ripser persistence: The previously calculated persistence data :param str output: The directory to save the output to """ # Plot a persistence diagram dgms = persistence['dgms'] pyplot.figure(figsize=(6, 6)) pyplot.title('Persistence Diagram') persim.plot_diagrams(dgms, show=False) pyplot.tight_layout() pyplot.savefig(output + 'persistence_diagram_ripser.svg')
def plot_ts_pd(ts, pd, figsize=(12, 6), save_img=False, path=None): """ plot a time series and associated persistence diagram side by side ts - time series to be plotted; numpy array - col 0 is time; col 1 is data pd - a persistence diagram represented by an array; ripser object figsize - default size of plot figure save_img - bool; indicate whether or not to save image file path - where to save image file; defaults to working dir if None ---- citation: https://ripser.scikit-tda.org/notebooks/Lower%20Star%20Time%20Series.html """ # create persistence diagram axis markers (dashed lines) allgrid = np.unique(pd["dgms"][0].flatten()) # unique persistence pts allgrid = allgrid[allgrid < np.inf] # do not mark final cycle births = np.unique(pd["dgms"][0][:, 0]) # unique birth times deaths = np.unique(pd["dgms"][0][:, 1]) # unique death times deaths = deaths[deaths < np.inf] # do not mark final cycle plt.figure(figsize=figsize) # plot the time series plt.subplot(121) plt.plot(ts[:, 0], ts[:, 1]) ax = plt.gca() ax.set_yticks(allgrid) ax.set_xticks([]) plt.grid(linewidth=1, linestyle='--') plt.xlabel("time (ms)") plt.ylabel("Amplitude") # plot the persistence diagram plt.subplot(122) ax = plt.gca() ax.set_xticks(births) ax.set_yticks(deaths) ax.tick_params(labelrotation=45) plt.grid(linewidth=1, linestyle='--') plot_diagrams(pd["dgms"][0], size=50) plt.title("Persistence Diagram") if not save_img: plt.show() elif path is not None: plt.savefig(path) plt.close() else: plt.savefig(os.curdir + "/ts_pd.png") plt.close()
def plot_diagram(self): ''' Plot birth-death diagram of the shape components (persistence diagram) :return: ax object ''' diagrams = ripser(self.points)['dgms'] return plot_diagrams(diagrams, show=True)
def plot_rm_sac_dgm(self, idx): plt.figure(figsize=(15, 4)) plt.subplot(131) plt.imshow(self.ratemaps_[idx], cmap='jet') plt.axis('off') plt.subplot(132) plt.imshow(self.sacs_[idx], cmap='jet') plt.axis('off') #convert dgm for sktda dgmskt = [] for j in list(set(self.dgms_[idx, :, 2])): h = self.dgms_[idx][np.where(self.dgms_[idx][:, 2] == j), :2].reshape( -1, 2) dgmskt.append(h) plt.subplot(133) plot_diagrams(dgmskt)
def test_multiple(self): diagrams = [ np.array([[0, 1], [1, 1], [2, 4], [3, 5]]), np.array([[0.5, 3], [2, 4], [4, 5], [10, 15]]) ] f, ax = plt.subplots() plot_diagrams(diagrams, show=False) pathcols = [ child for child in ax.get_children() if child.__class__.__name__ == "PathCollection" ] assert len(pathcols) == 2 np.testing.assert_array_equal(pathcols[0].get_offsets(), diagrams[0]) np.testing.assert_array_equal(pathcols[1].get_offsets(), diagrams[1])
def calc_TDA(self, epoch, cls_num): path = utils.make_directory( os.path.join(utils.default_model_dir, 'tda_total', str(cls_num))) path2 = utils.make_directory( os.path.join(utils.default_model_dir, 'tda_sub', str(cls_num))) dgms = ripser(self.z.data, maxdim=3)['dgms'] plot_diagrams(dgms) plt.savefig('{}/{}_total.png'.format(path, epoch)) plt.clf() if len(dgms[0]) is not 0: plot_diagrams(dgms, plot_only=[0], ax=subplot(221)) if len(dgms[1]) is not 0: plot_diagrams(dgms, plot_only=[1], ax=subplot(222)) if len(dgms[2]) is not 0: plot_diagrams(dgms, plot_only=[2], ax=subplot(223)) if len(dgms[3]) is not 0: plot_diagrams(dgms, plot_only=[3], ax=subplot(224)) plt.savefig('{}/{}_sub.png'.format(path2, epoch)) plt.clf()
def test_single(self): """ Most just test this doesn't crash """ diagram = np.array([[0, 1], [1, 1], [2, 4], [3, 5]]) f, ax = plt.subplots() plot_diagrams(diagram, show=False) x_plot, y_plot = ax.lines[0].get_xydata().T assert x_plot[0] <= np.min(diagram) assert x_plot[1] >= np.max(diagram) # get PathCollection pathcols = [ child for child in ax.get_children() if child.__class__.__name__ == "PathCollection" ] assert len(pathcols) == 1
def test_lifetime_removes_birth(self): diagrams = [ np.array([[0, 1], [1, 1], [2, 4], [3, 5]]), np.array([[0.5, 3], [2, 4], [4, 5], [10, 15]]) ] f, ax = plt.subplots() plot_diagrams(diagrams, lifetime=True, show=False) pathcols = [ child for child in ax.get_children() if child.__class__.__name__ == "PathCollection" ] modded1 = diagrams[0] modded1[:, 1] = diagrams[0][:, 1] - diagrams[0][:, 0] modded2 = diagrams[1] modded2[:, 1] = diagrams[1][:, 1] - diagrams[1][:, 0] assert len(pathcols) == 2 np.testing.assert_array_equal(pathcols[0].get_offsets(), modded1) np.testing.assert_array_equal(pathcols[1].get_offsets(), modded2)
def alphaFigure(): np.random.seed(0) X = np.random.randn(20, 2) X /= np.sqrt(np.sum(X**2, 1))[:, None] X += 0.2 * np.random.randn(X.shape[0], 2) alpha = cm.Alpha() filtration = alpha.build(X) dgmsalpha = alpha.diagrams(filtration) plt.figure(figsize=(16, 4)) scales = [0.2, 0.45, 0.9] N = len(scales) + 1 for i, s in enumerate(scales): plt.subplot(1, N, i + 1) if i == 0: drawAlpha(X, filtration, s, True) else: drawAlpha(X, filtration, s, True) plt.title("$\\alpha = %.3g$" % s) plt.subplot(1, N, N) plot_diagrams(dgmsalpha) for scale in scales: plt.plot([-0.01, scale], [scale, scale], 'gray', linestyle='--', linewidth=1, zorder=0) plt.plot([scale, scale], [scale, 1.0], 'gray', linestyle='--', linewidth=1, zorder=0) plt.text(scale + 0.01, scale - 0.01, "%.3g" % scale) plt.title("Persistence Diagram") plt.savefig("Alpha.svg", bbox_inches='tight')
def plot(self, diagrams=None, *args, **kwargs): """A helper function to plot persistence diagrams. Parameters ---------- diagrams: ndarray (n_pairs, 2) or list of diagrams A diagram or list of diagrams as returned from self.fit. If diagram is None, we use `self.dgm_` for plotting. If diagram is a list of diagrams, then plot all on the same plot using different colors. plot_only: list of numeric If specified, an array of only the diagrams that should be plotted. title: string, default is None If title is defined, add it as title of the plot. xy_range: list of numeric [xmin, xmax, ymin, ymax] User provided range of axes. This is useful for comparing multiple persistence diagrams. labels: string or list of strings Legend labels for each diagram. If none are specified, we use H_0, H_1, H_2,... by default. colormap: string, default is 'default' Any of matplotlib color palettes. Some options are 'default', 'seaborn', 'sequential'. See all available styles with .. code:: python import matplotlib as mpl print(mpl.styles.available) size: numeric, default is 20 Pixel size of each point plotted. ax_color: any valid matplitlib color type. See [https://matplotlib.org/api/colors_api.html](https://matplotlib.org/api/colors_api.html) for complete API. diagonal: bool, default is True Plot the diagonal x=y line. lifetime: bool, default is False. If True, diagonal is turned to False. Plot life time of each point instead of birth and death. Essentially, visualize (x, y-x). legend: bool, default is True If true, show the legend. show: bool, default is True Call plt.show() after plotting. If you are using self.plot() as part of a subplot, set show=False and call plt.show() only once at the end. """ if diagrams is None: # Allow using transformed diagrams as default diagrams = self.dgms_ persim.plot_diagrams(diagrams, *args, **kwargs)
from ripser import ripser from persim import plot_diagrams import matplotlib.pyplot as plt import numpy as np from sklearn import datasets #np.random.seed(5) RAND = np.random.randint(50001) with np.load('mnist.npz') as data: # data is stored in 28 by 28 images (784 brightness values) # training data and labels will be stored in 2D arrays - there are 50000 training samples, thus .shape = (50000,784) training_images = data['training_images'] training_labels = data['training_labels'] training_images = training_images.reshape(50000,28,28) dgms = ripser(training_images[RAND])['dgms'] plot_diagrams(dgms, show=True) plot_diagrams(dgms, plot_only=[0], ax=plt.subplot(121)) plot_diagrams(dgms, plot_only=[1], ax=plt.subplot(122)) fig, ax = plt.subplots() plt.imshow(training_images[RAND]) plt.show()
feature_list = [] # Initialize a noisy circle X = tadasets.dsphere(n=100, d=1, r=1, noise=0.2) # Instantiate and build a rips filtration rips = cm.Rips(1) #Go up to 1D homology rips.build(X) dgmsrips = rips.diagrams() plt.subplot(121) plt.scatter(X[:, 0], X[:, 1]) plt.axis('square') plt.title("Point Cloud") plt.subplot(122) plot_diagrams(dgmsrips) plt.title("Rips Persistence Diagrams") plt.tight_layout() plt.show() # data_test = np.random.random((100,2)) #data = im_label #fdata = pd.concat(feature_list, axis=1) #print fdata if __name__ == "__main__": main(CLIArgumentParser().parse_args())
def plot( self, diagrams=None, *args, **kwargs ): """A helper function to plot persistence diagrams. Parameters ---------- diagrams: ndarray (n_pairs, 2) or list of diagrams A diagram or list of diagrams as returned from self.fit. If diagram is None, we use `self.dgm_` for plotting. If diagram is a list of diagrams, then plot all on the same plot using different colors. plot_only: list of numeric If specified, an array of only the diagrams that should be plotted. title: string, default is None If title is defined, add it as title of the plot. xy_range: list of numeric [xmin, xmax, ymin, ymax] User provided range of axes. This is useful for comparing multiple persistence diagrams. labels: string or list of strings Legend labels for each diagram. If none are specified, we use H_0, H_1, H_2,... by default. colormap: string, default is 'default' Any of matplotlib color palettes. Some options are 'default', 'seaborn', 'sequential'. See all available styles with .. code:: python import matplotlib as mpl print(mpl.styles.available) size: numeric, default is 20 Pixel size of each point plotted. ax_color: any valid matplitlib color type. See [https://matplotlib.org/api/colors_api.html](https://matplotlib.org/api/colors_api.html) for complete API. diagonal: bool, default is True Plot the diagonal x=y line. lifetime: bool, default is False. If True, diagonal is turned to False. Plot life time of each point instead of birth and death. Essentially, visualize (x, y-x). legend: bool, default is True If true, show the legend. show: bool, default is True Call plt.show() after plotting. If you are using self.plot() as part of a subplot, set show=False and call plt.show() only once at the end. """ if diagrams is None: # Allow using transformed diagrams as default diagrams = self.dgms_ persim.plot_diagrams( diagrams, *args, **kwargs )
lens_names=[], show_tooltips=True, nbins=10) import IPython url = 'mapper_visualization_output.html' iframe = '<iframe src=' + url + ' width=700 height=600></iframe>' IPython.display.HTML(iframe) #mean center the filters f_min, f_max = filters.min(), filters.max() filters = (filters - f_min) / (f_max - f_min) #change this #visualize the filters n_filters, ix = 6, 1 for i in range(n_filters): f = filters[:, :, :, i] for j in range(3): ax = pyplot.subplot(n_filters, 3, ix) ax.set_xticks([]) ax.set_yticks([]) pyplot.imshow(f[:, :, j], cmap='gray') ix += 1 pyplot.show() pca.fit(raw_data_arr) print(pca.explained_variance_ratio_) print(pca.singular_values_) #datas = numpy.random.random((100,2)) #data = simplicial_complex #print(data) diagrams = ripser(projected_data)['dgms'] plot_diagrams(diagrams, show=True)
plt.figure() plt.imshow(a.reshape(28, 28), cmap='Greys') plt.show() return a adv_ex = generate(2) adv_ex = adv_ex.reshape(28, 28) adv_dgms = ripser(adv_ex)['dgms'] print("Homology of Adversarial Example: ") plt.figure() plot_diagrams(adv_dgms, plot_only=[0], ax=plt.subplot(121)) plot_diagrams(adv_dgms, plot_only=[1], ax=plt.subplot(122)) plt.show() # 3D Height Plots xx, yy = np.mgrid[0:adv_ex.shape[0], 0:adv_ex.shape[1]] fig = plt.figure() ax1 = Axes3D(fig) ax1.plot_surface(xx, yy, adv_ex, rstride=1, cstride=1, cmap=plt.cm.gray, linewidth=0)
c = np.linalg.norm(data, axis=1) cc = np.reshape(c, (20, 20)) fig, ax = plt.subplots() ax.imshow(cc, cmap='cividis') plt.show() # %% codecell # Compute the distance matrix and persistence. D = sp.spatial.distance.cdist(data, data, metric='euclidean') # TODO: improve this maxmin function. sub_ind = pipeline.maxmin_subsample_distance_matrix(D, n_landmarks, seed=[57])['indices'] D_sub = D[sub_ind, :][:, sub_ind] p = 13 PH = ripser(D_sub, distance_matrix=True, maxdim=2, coeff=p, do_cocycles=True) plot_diagrams(PH['dgms']) plt_title = 'Persistence Diagram (coefficients in $\mathbb{F}_{%d}$)' % p plt.title(plt_title) plt.show() # If the parameters are chosen well the PH should have a nice H^2 class. # %% codecell # Set up a random initial condition. rng = np.random.default_rng(57) X_rand = rng.uniform(-1, 1, (4, n_landmarks + 1)) # X_rand = rng.uniform(-1, 1, (4, K**2)) X_rand = X_rand / np.linalg.norm(X_rand, axis=0) # %% codecell # Note that these distance matrices are restricted to the landmark points. # Because many distances are near zero, the weights computed for the geodesic
# Analyse topology diagrams = ripser(data, maxdim=data.shape[1]-1)['dgms'] # Plot results fig = plt.figure() fig.set_figwidth(5); fig.set_figheight(15) if data.shape[1]==3: ax1 = fig.add_subplot(211, projection='3d') ax1.scatter(data[:,0],data[:,1],data[:,2]) else: ax1 = fig.add_subplot(211) ax1.scatter(data[:,0],data[:,1]) ax1.set_title('Data') ax2 = fig.add_subplot(212) plot_diagrams(diagrams, show=True, ax=ax2) plt.show() ''' Note that this second graph shows the persistant of different n-dimensional homologies. These dimensions can be referred to using Betti number: - b0 is the number of connected components - b1 is the number of one-dimensional or "circular" holes - b2 is the number of two-dimensional "voids" or "cavities" In this script, you will see that, when the data form clusters, there are h0 dots that have significantly higher death value than the diagonal line (indicating persistent homology, and the presence of clusters in the data). The number of these dots should be equal to the number of clusters. Alternatively, when the data is a 2D ring, there is a h1 dot that has a signficantly higher death value than the diagonal line (indicating persistent homology, and the presence of a circular hole in the data). However, when the data is a sphere, there is an h2 dot that has a signficantly higher death value than the diagonal line (indicating persistent homology, and the presence of a void (or cavity) hole in the data). In contrast to both, when data is taken from a torus, there is evidence of both a b1 and b2 holes.
# imports import pdbutils import elemSpecificPH import scipy from ripser import ripser from persim import plot_diagrams import matplotlib.pyplot as plt # %% # get the structure struc = pdbutils.createStruct("6VXX.pdb") # %% # separate it by its elements coords = elemSpecificPH.getPositionArray(struc) # %% strucarray = elemSpecificPH.struc2elemPosArrays(struc) # %% a = strucarray[1] #a = scipy.spatial.distance.pdist(strucarray) # %% diagrams = ripser(a)['dgms'] # %% plot_diagrams(diagrams, show=False) plt.savefig("persistent_homology.png")