From 34e1ae726e27fdd7c41f6d80d8ed7f6504dc3a0d Mon Sep 17 00:00:00 2001 From: tlacombe Date: Fri, 14 Feb 2020 18:16:27 +0100 Subject: Global improvement of rendering with Python tools --- src/python/gudhi/persistence_graphical_tools.py | 92 +++++++++++++++++++++---- 1 file changed, 77 insertions(+), 15 deletions(-) (limited to 'src/python') diff --git a/src/python/gudhi/persistence_graphical_tools.py b/src/python/gudhi/persistence_graphical_tools.py index 246280de..4a690241 100644 --- a/src/python/gudhi/persistence_graphical_tools.py +++ b/src/python/gudhi/persistence_graphical_tools.py @@ -5,6 +5,7 @@ # Copyright (C) 2016 Inria # # Modification(s): +# - 2020/02 Theo Lacombe: Added more options for improved rendering and more flexibility. # - YYYY/MM Author: Description of the modification from os import path @@ -43,6 +44,7 @@ def __min_birth_max_death(persistence, band=0.0): max_death += band return (min_birth, max_death) + def plot_persistence_barcode( persistence=[], persistence_file="", @@ -52,7 +54,9 @@ def plot_persistence_barcode( inf_delta=0.1, legend=False, colormap=None, - axes=None + axes=None, + fontsize=16, + title="Persistence barcode" ): """This function plots the persistence bar code from persistence values list or from a :doc:`persistence file `. @@ -81,11 +85,18 @@ def plot_persistence_barcode( :param axes: A matplotlib-like subplot axes. If None, the plot is drawn on a new set of axes. :type axes: `matplotlib.axes.Axes` + :param fontsize: Fontsize to use in axis. + :type fontsize: int + :param title: title for the plot. + :type title: string :returns: (`matplotlib.axes.Axes`): The axes on which the plot was drawn. """ try: import matplotlib.pyplot as plt import matplotlib.patches as mpatches + from matplotlib import rc + plt.rc('text', usetex=True) + plt.rc('font', family='serif') if persistence_file != "": if path.isfile(persistence_file): @@ -163,7 +174,7 @@ def plot_persistence_barcode( loc="lower right", ) - axes.set_title("Persistence barcode") + axes.set_title(title) # Ends plot on infinity value and starts a little bit before min_birth axes.axis([axis_start, infinity, 0, ind]) @@ -183,7 +194,11 @@ def plot_persistence_diagram( inf_delta=0.1, legend=False, colormap=None, - axes=None + axes=None, + aspect_equal=False, + fontsize=16, + title="Persistence diagram", + greyblock=True ): """This function plots the persistence diagram from persistence values list or from a :doc:`persistence file `. @@ -214,11 +229,23 @@ def plot_persistence_diagram( :param axes: A matplotlib-like subplot axes. If None, the plot is drawn on a new set of axes. :type axes: `matplotlib.axes.Axes` + :param aspect_equal: if True, force plot to be square shaped. + :type aspect_equal: boolean + :param fontsize: Fontsize to use in axis. + :type fontsize: int + :param title: title for the plot. + :type title: string + :param greyblock: if we want to plot a grey patch on the lower half plane for nicer rendering. Default True. + :type greyblock: boolean :returns: (`matplotlib.axes.Axes`): The axes on which the plot was drawn. """ try: import matplotlib.pyplot as plt import matplotlib.patches as mpatches + from matplotlib import rc + plt.rc('text', usetex=True) + plt.rc('font', family='serif') + if persistence_file != "": if path.isfile(persistence_file): @@ -256,18 +283,27 @@ def plot_persistence_diagram( # Replace infinity values with max_death + delta for diagram to be more # readable infinity = max_death + delta + axis_end = max_death + delta / 2 axis_start = min_birth - delta # line display of equation : birth = death x = np.linspace(axis_start, infinity, 1000) # infinity line and text - axes.plot(x, x, color="k", linewidth=1.0) - axes.plot(x, [infinity] * len(x), linewidth=1.0, color="k", alpha=alpha) - axes.text(axis_start, infinity, r"$\infty$", color="k", alpha=alpha) + axes.plot([axis_start, axis_end], [axis_start, axis_end], linewidth=1.0, color="k") + axes.plot([axis_start, axis_end], [infinity, infinity], linewidth=1.0, color="k", alpha=alpha) + # Infinity label + yt = axes.get_yticks() + yt = np.append(yt, infinity) + ytl = yt.tolist() + ytl[-1] = r'$+\infty$' + axes.set_yticks(yt) + axes.set_yticklabels(ytl) # bootstrap band if band > 0.0: axes.fill_between(x, x, x + band, alpha=alpha, facecolor="red") - + # lower diag patch + if greyblock: + axes.add_patch(mpatches.Polygon([[axis_start, axis_start], [axis_end, axis_start], [axis_end, axis_end]], fill=True, color='lightgrey')) # Draw points in loop for interval in reversed(persistence): if float(interval[1][1]) != float("inf"): @@ -293,11 +329,13 @@ def plot_persistence_diagram( ] ) - axes.set_xlabel("Birth") - axes.set_ylabel("Death") + axes.set_xlabel("Birth", fontsize=fontsize) + axes.set_ylabel("Death", fontsize=fontsize) # Ends plot on infinity value and starts a little bit before min_birth - axes.axis([axis_start, infinity, axis_start, infinity + delta]) - axes.set_title("Persistence diagram") + axes.axis([axis_start, axis_end, axis_start, infinity + delta]) + axes.set_title(title, fontsize=fontsize) # a different fontsize for the title? + if aspect_equal: + axes.set_aspect("equal") return axes except ImportError: @@ -313,7 +351,11 @@ def plot_persistence_density( dimension=None, cmap=None, legend=False, - axes=None + axes=None, + aspect_equal=False, + fontsize=16, + title="Persistence density", + greyblock=True ): """This function plots the persistence density from persistence values list or from a :doc:`persistence file `. Be @@ -355,11 +397,25 @@ def plot_persistence_density( :param axes: A matplotlib-like subplot axes. If None, the plot is drawn on a new set of axes. :type axes: `matplotlib.axes.Axes` + :param aspect_equal: if True, force plot to be square shaped. + :type aspect_equal: boolean + :param fontsize: Fontsize to use in axis. + :type fontsize: int + :param title: title for the plot. + :type title: string + :param greyblock: if we want to plot a grey patch on the lower half plane + for nicer rendering. Default True. + :type greyblock: boolean :returns: (`matplotlib.axes.Axes`): The axes on which the plot was drawn. """ try: import matplotlib.pyplot as plt + import matplotlib.patches as mpatches from scipy.stats import kde + from matplotlib import rc + plt.rc('text', usetex=True) + plt.rc('font', family='serif') + if persistence_file != "": if dimension is None: @@ -418,12 +474,18 @@ def plot_persistence_density( # Make the plot img = axes.pcolormesh(xi, yi, zi.reshape(xi.shape), cmap=cmap) + if greyblock: + axes.add_patch(mpatches.Polygon([[birth.min(), birth.min()], [death.max(), birth.min()], [death.max(), death.max()]], fill=True, color='lightgrey')) + if legend: plt.colorbar(img, ax=axes) - axes.set_xlabel("Birth") - axes.set_ylabel("Death") - axes.set_title("Persistence density") + axes.set_xlabel("Birth", fontsize=fontsize) + axes.set_ylabel("Death", fontsize=fontsize) + axes.set_title(title, fontsize=fontsize) + if aspect_equal: + axes.set_aspect("equal") + return axes except ImportError: -- cgit v1.2.3 From 835a831007196a4d93e57659ab8d3cdb28a4ef92 Mon Sep 17 00:00:00 2001 From: tlacombe Date: Tue, 25 Feb 2020 18:14:06 +0100 Subject: Revert "Global improvement of rendering with Python tools" This reverts commit 34e1ae726e27fdd7c41f6d80d8ed7f6504dc3a0d. --- src/python/gudhi/persistence_graphical_tools.py | 92 ++++--------------------- 1 file changed, 15 insertions(+), 77 deletions(-) (limited to 'src/python') diff --git a/src/python/gudhi/persistence_graphical_tools.py b/src/python/gudhi/persistence_graphical_tools.py index 4a690241..246280de 100644 --- a/src/python/gudhi/persistence_graphical_tools.py +++ b/src/python/gudhi/persistence_graphical_tools.py @@ -5,7 +5,6 @@ # Copyright (C) 2016 Inria # # Modification(s): -# - 2020/02 Theo Lacombe: Added more options for improved rendering and more flexibility. # - YYYY/MM Author: Description of the modification from os import path @@ -44,7 +43,6 @@ def __min_birth_max_death(persistence, band=0.0): max_death += band return (min_birth, max_death) - def plot_persistence_barcode( persistence=[], persistence_file="", @@ -54,9 +52,7 @@ def plot_persistence_barcode( inf_delta=0.1, legend=False, colormap=None, - axes=None, - fontsize=16, - title="Persistence barcode" + axes=None ): """This function plots the persistence bar code from persistence values list or from a :doc:`persistence file `. @@ -85,18 +81,11 @@ def plot_persistence_barcode( :param axes: A matplotlib-like subplot axes. If None, the plot is drawn on a new set of axes. :type axes: `matplotlib.axes.Axes` - :param fontsize: Fontsize to use in axis. - :type fontsize: int - :param title: title for the plot. - :type title: string :returns: (`matplotlib.axes.Axes`): The axes on which the plot was drawn. """ try: import matplotlib.pyplot as plt import matplotlib.patches as mpatches - from matplotlib import rc - plt.rc('text', usetex=True) - plt.rc('font', family='serif') if persistence_file != "": if path.isfile(persistence_file): @@ -174,7 +163,7 @@ def plot_persistence_barcode( loc="lower right", ) - axes.set_title(title) + axes.set_title("Persistence barcode") # Ends plot on infinity value and starts a little bit before min_birth axes.axis([axis_start, infinity, 0, ind]) @@ -194,11 +183,7 @@ def plot_persistence_diagram( inf_delta=0.1, legend=False, colormap=None, - axes=None, - aspect_equal=False, - fontsize=16, - title="Persistence diagram", - greyblock=True + axes=None ): """This function plots the persistence diagram from persistence values list or from a :doc:`persistence file `. @@ -229,23 +214,11 @@ def plot_persistence_diagram( :param axes: A matplotlib-like subplot axes. If None, the plot is drawn on a new set of axes. :type axes: `matplotlib.axes.Axes` - :param aspect_equal: if True, force plot to be square shaped. - :type aspect_equal: boolean - :param fontsize: Fontsize to use in axis. - :type fontsize: int - :param title: title for the plot. - :type title: string - :param greyblock: if we want to plot a grey patch on the lower half plane for nicer rendering. Default True. - :type greyblock: boolean :returns: (`matplotlib.axes.Axes`): The axes on which the plot was drawn. """ try: import matplotlib.pyplot as plt import matplotlib.patches as mpatches - from matplotlib import rc - plt.rc('text', usetex=True) - plt.rc('font', family='serif') - if persistence_file != "": if path.isfile(persistence_file): @@ -283,27 +256,18 @@ def plot_persistence_diagram( # Replace infinity values with max_death + delta for diagram to be more # readable infinity = max_death + delta - axis_end = max_death + delta / 2 axis_start = min_birth - delta # line display of equation : birth = death x = np.linspace(axis_start, infinity, 1000) # infinity line and text - axes.plot([axis_start, axis_end], [axis_start, axis_end], linewidth=1.0, color="k") - axes.plot([axis_start, axis_end], [infinity, infinity], linewidth=1.0, color="k", alpha=alpha) - # Infinity label - yt = axes.get_yticks() - yt = np.append(yt, infinity) - ytl = yt.tolist() - ytl[-1] = r'$+\infty$' - axes.set_yticks(yt) - axes.set_yticklabels(ytl) + axes.plot(x, x, color="k", linewidth=1.0) + axes.plot(x, [infinity] * len(x), linewidth=1.0, color="k", alpha=alpha) + axes.text(axis_start, infinity, r"$\infty$", color="k", alpha=alpha) # bootstrap band if band > 0.0: axes.fill_between(x, x, x + band, alpha=alpha, facecolor="red") - # lower diag patch - if greyblock: - axes.add_patch(mpatches.Polygon([[axis_start, axis_start], [axis_end, axis_start], [axis_end, axis_end]], fill=True, color='lightgrey')) + # Draw points in loop for interval in reversed(persistence): if float(interval[1][1]) != float("inf"): @@ -329,13 +293,11 @@ def plot_persistence_diagram( ] ) - axes.set_xlabel("Birth", fontsize=fontsize) - axes.set_ylabel("Death", fontsize=fontsize) + axes.set_xlabel("Birth") + axes.set_ylabel("Death") # Ends plot on infinity value and starts a little bit before min_birth - axes.axis([axis_start, axis_end, axis_start, infinity + delta]) - axes.set_title(title, fontsize=fontsize) # a different fontsize for the title? - if aspect_equal: - axes.set_aspect("equal") + axes.axis([axis_start, infinity, axis_start, infinity + delta]) + axes.set_title("Persistence diagram") return axes except ImportError: @@ -351,11 +313,7 @@ def plot_persistence_density( dimension=None, cmap=None, legend=False, - axes=None, - aspect_equal=False, - fontsize=16, - title="Persistence density", - greyblock=True + axes=None ): """This function plots the persistence density from persistence values list or from a :doc:`persistence file `. Be @@ -397,25 +355,11 @@ def plot_persistence_density( :param axes: A matplotlib-like subplot axes. If None, the plot is drawn on a new set of axes. :type axes: `matplotlib.axes.Axes` - :param aspect_equal: if True, force plot to be square shaped. - :type aspect_equal: boolean - :param fontsize: Fontsize to use in axis. - :type fontsize: int - :param title: title for the plot. - :type title: string - :param greyblock: if we want to plot a grey patch on the lower half plane - for nicer rendering. Default True. - :type greyblock: boolean :returns: (`matplotlib.axes.Axes`): The axes on which the plot was drawn. """ try: import matplotlib.pyplot as plt - import matplotlib.patches as mpatches from scipy.stats import kde - from matplotlib import rc - plt.rc('text', usetex=True) - plt.rc('font', family='serif') - if persistence_file != "": if dimension is None: @@ -474,18 +418,12 @@ def plot_persistence_density( # Make the plot img = axes.pcolormesh(xi, yi, zi.reshape(xi.shape), cmap=cmap) - if greyblock: - axes.add_patch(mpatches.Polygon([[birth.min(), birth.min()], [death.max(), birth.min()], [death.max(), death.max()]], fill=True, color='lightgrey')) - if legend: plt.colorbar(img, ax=axes) - axes.set_xlabel("Birth", fontsize=fontsize) - axes.set_ylabel("Death", fontsize=fontsize) - axes.set_title(title, fontsize=fontsize) - if aspect_equal: - axes.set_aspect("equal") - + axes.set_xlabel("Birth") + axes.set_ylabel("Death") + axes.set_title("Persistence density") return axes except ImportError: -- cgit v1.2.3 From cdcd2904a1c682625670a62608fd781bfd571516 Mon Sep 17 00:00:00 2001 From: tlacombe Date: Tue, 25 Feb 2020 18:19:24 +0100 Subject: solved scale issue and removed title/aspect as functions return ax --- src/python/gudhi/persistence_graphical_tools.py | 77 +++++++++++++++++++------ 1 file changed, 60 insertions(+), 17 deletions(-) (limited to 'src/python') diff --git a/src/python/gudhi/persistence_graphical_tools.py b/src/python/gudhi/persistence_graphical_tools.py index 246280de..8ddfdba8 100644 --- a/src/python/gudhi/persistence_graphical_tools.py +++ b/src/python/gudhi/persistence_graphical_tools.py @@ -5,6 +5,7 @@ # Copyright (C) 2016 Inria # # Modification(s): +# - 2020/02 Theo Lacombe: Added more options for improved rendering and more flexibility. # - YYYY/MM Author: Description of the modification from os import path @@ -43,6 +44,7 @@ def __min_birth_max_death(persistence, band=0.0): max_death += band return (min_birth, max_death) + def plot_persistence_barcode( persistence=[], persistence_file="", @@ -52,7 +54,8 @@ def plot_persistence_barcode( inf_delta=0.1, legend=False, colormap=None, - axes=None + axes=None, + fontsize=16, ): """This function plots the persistence bar code from persistence values list or from a :doc:`persistence file `. @@ -81,11 +84,16 @@ def plot_persistence_barcode( :param axes: A matplotlib-like subplot axes. If None, the plot is drawn on a new set of axes. :type axes: `matplotlib.axes.Axes` + :param fontsize: Fontsize to use in axis. + :type fontsize: int :returns: (`matplotlib.axes.Axes`): The axes on which the plot was drawn. """ try: import matplotlib.pyplot as plt import matplotlib.patches as mpatches + from matplotlib import rc + plt.rc('text', usetex=True) + plt.rc('font', family='serif') if persistence_file != "": if path.isfile(persistence_file): @@ -163,7 +171,7 @@ def plot_persistence_barcode( loc="lower right", ) - axes.set_title("Persistence barcode") + axes.set_title("Persistence barcode", fontsize=fontsize) # Ends plot on infinity value and starts a little bit before min_birth axes.axis([axis_start, infinity, 0, ind]) @@ -183,7 +191,9 @@ def plot_persistence_diagram( inf_delta=0.1, legend=False, colormap=None, - axes=None + axes=None, + fontsize=16, + greyblock=True ): """This function plots the persistence diagram from persistence values list or from a :doc:`persistence file `. @@ -214,11 +224,19 @@ def plot_persistence_diagram( :param axes: A matplotlib-like subplot axes. If None, the plot is drawn on a new set of axes. :type axes: `matplotlib.axes.Axes` + :param fontsize: Fontsize to use in axis. + :type fontsize: int + :param greyblock: if we want to plot a grey patch on the lower half plane for nicer rendering. Default True. + :type greyblock: boolean :returns: (`matplotlib.axes.Axes`): The axes on which the plot was drawn. """ try: import matplotlib.pyplot as plt import matplotlib.patches as mpatches + from matplotlib import rc + plt.rc('text', usetex=True) + plt.rc('font', family='serif') + if persistence_file != "": if path.isfile(persistence_file): @@ -256,18 +274,27 @@ def plot_persistence_diagram( # Replace infinity values with max_death + delta for diagram to be more # readable infinity = max_death + delta + axis_end = max_death + delta / 2 axis_start = min_birth - delta - # line display of equation : birth = death - x = np.linspace(axis_start, infinity, 1000) # infinity line and text - axes.plot(x, x, color="k", linewidth=1.0) - axes.plot(x, [infinity] * len(x), linewidth=1.0, color="k", alpha=alpha) - axes.text(axis_start, infinity, r"$\infty$", color="k", alpha=alpha) + axes.plot([axis_start, axis_end], [axis_start, axis_end], linewidth=1.0, color="k") + axes.plot([axis_start, axis_end], [infinity, infinity], linewidth=1.0, color="k", alpha=alpha) + # Infinity label + yt = axes.get_yticks() + yt = yt[np.where(yt < axis_end)] # to avoid ploting ticklabel higher than infinity + yt = np.append(yt, infinity) + ytl = ["%.3f" % e for e in yt] # to avoid float precision error + ytl[-1] = r'$+\infty$' + axes.set_yticks(yt) + axes.set_yticklabels(ytl) # bootstrap band if band > 0.0: + x = np.linspace(axis_start, infinity, 1000) axes.fill_between(x, x, x + band, alpha=alpha, facecolor="red") - + # lower diag patch + if greyblock: + axes.add_patch(mpatches.Polygon([[axis_start, axis_start], [axis_end, axis_start], [axis_end, axis_end]], fill=True, color='lightgrey')) # Draw points in loop for interval in reversed(persistence): if float(interval[1][1]) != float("inf"): @@ -293,11 +320,11 @@ def plot_persistence_diagram( ] ) - axes.set_xlabel("Birth") - axes.set_ylabel("Death") + axes.set_xlabel("Birth", fontsize=fontsize) + axes.set_ylabel("Death", fontsize=fontsize) + axes.set_title("Persistence diagram", fontsize=fontsize) # Ends plot on infinity value and starts a little bit before min_birth - axes.axis([axis_start, infinity, axis_start, infinity + delta]) - axes.set_title("Persistence diagram") + axes.axis([axis_start, axis_end, axis_start, infinity + delta/2]) return axes except ImportError: @@ -313,7 +340,9 @@ def plot_persistence_density( dimension=None, cmap=None, legend=False, - axes=None + axes=None, + fontsize=16, + greyblock=True ): """This function plots the persistence density from persistence values list or from a :doc:`persistence file `. Be @@ -355,11 +384,21 @@ def plot_persistence_density( :param axes: A matplotlib-like subplot axes. If None, the plot is drawn on a new set of axes. :type axes: `matplotlib.axes.Axes` + :param fontsize: Fontsize to use in axis. + :type fontsize: int + :param greyblock: if we want to plot a grey patch on the lower half plane + for nicer rendering. Default True. + :type greyblock: boolean :returns: (`matplotlib.axes.Axes`): The axes on which the plot was drawn. """ try: import matplotlib.pyplot as plt + import matplotlib.patches as mpatches from scipy.stats import kde + from matplotlib import rc + plt.rc('text', usetex=True) + plt.rc('font', family='serif') + if persistence_file != "": if dimension is None: @@ -418,12 +457,16 @@ def plot_persistence_density( # Make the plot img = axes.pcolormesh(xi, yi, zi.reshape(xi.shape), cmap=cmap) + if greyblock: + axes.add_patch(mpatches.Polygon([[birth.min(), birth.min()], [death.max(), birth.min()], [death.max(), death.max()]], fill=True, color='lightgrey')) + if legend: plt.colorbar(img, ax=axes) - axes.set_xlabel("Birth") - axes.set_ylabel("Death") - axes.set_title("Persistence density") + axes.set_xlabel("Birth", fontsize=fontsize) + axes.set_ylabel("Death", fontsize=fontsize) + axes.set_title("Persistence density", fontsize=fontsize) + return axes except ImportError: -- cgit v1.2.3 From 3ecf0caf4efbea0fabf4af0df490900374abda8b Mon Sep 17 00:00:00 2001 From: tlacombe Date: Tue, 25 Feb 2020 18:20:30 +0100 Subject: say in doc that functions return ax --- src/python/doc/persistence_graphical_tools_sum.inc | 6 +++--- src/python/doc/persistence_graphical_tools_user.rst | 20 ++++++++++++-------- 2 files changed, 15 insertions(+), 11 deletions(-) (limited to 'src/python') diff --git a/src/python/doc/persistence_graphical_tools_sum.inc b/src/python/doc/persistence_graphical_tools_sum.inc index 0cdf8072..2ddaccfc 100644 --- a/src/python/doc/persistence_graphical_tools_sum.inc +++ b/src/python/doc/persistence_graphical_tools_sum.inc @@ -3,10 +3,10 @@ +-----------------------------------------------------------------+-----------------------------------------------------------------------+-----------------------------------------------+ | .. figure:: | These graphical tools comes on top of persistence results and allows | :Author: Vincent Rouvreau | - | img/graphical_tools_representation.png | the user to build easily persistence barcode, diagram or density. | | + | img/graphical_tools_representation.png | the user to display easily persistence barcode, diagram or density. | | | | | :Introduced in: GUDHI 2.0.0 | - | | | | - | | | :Copyright: MIT | + | | Note that these functions return the matplotlib axis, allowing | | + | | for further modifications (title, aspect, etc.) | :Copyright: MIT | | | | | | | | :Requires: matplotlib, numpy and scipy | +-----------------------------------------------------------------+-----------------------------------------------------------------------+-----------------------------------------------+ diff --git a/src/python/doc/persistence_graphical_tools_user.rst b/src/python/doc/persistence_graphical_tools_user.rst index 80002db6..ff51604e 100644 --- a/src/python/doc/persistence_graphical_tools_user.rst +++ b/src/python/doc/persistence_graphical_tools_user.rst @@ -20,7 +20,7 @@ This function can display the persistence result as a barcode: .. plot:: :include-source: - import matplotlib.pyplot as plot + import matplotlib.pyplot as plt import gudhi off_file = gudhi.__root_source_dir__ + '/data/points/tore3D_300.off' @@ -31,7 +31,7 @@ This function can display the persistence result as a barcode: diag = simplex_tree.persistence(min_persistence=0.4) gudhi.plot_persistence_barcode(diag) - plot.show() + plt.show() Show persistence as a diagram ----------------------------- @@ -44,15 +44,19 @@ This function can display the persistence result as a diagram: .. plot:: :include-source: - import matplotlib.pyplot as plot + import matplotlib.pyplot as plt import gudhi # rips_on_tore3D_1307.pers obtained from write_persistence_diagram method persistence_file=gudhi.__root_source_dir__ + \ '/data/persistence_diagram/rips_on_tore3D_1307.pers' - gudhi.plot_persistence_diagram(persistence_file=persistence_file, + ax = gudhi.plot_persistence_diagram(persistence_file=persistence_file, legend=True) - plot.show() + # We can modify the title, aspect, etc. + ax.set_title("Persistence diagram of a torus") + ax.set_aspect("equal") # forces to be square shaped + plt.show() + Persistence density ------------------- @@ -65,7 +69,7 @@ If you want more information on a specific dimension, for instance: .. plot:: :include-source: - import matplotlib.pyplot as plot + import matplotlib.pyplot as plt import gudhi # rips_on_tore3D_1307.pers obtained from write_persistence_diagram method persistence_file=gudhi.__root_source_dir__ + \ @@ -75,9 +79,9 @@ If you want more information on a specific dimension, for instance: only_this_dim=1) pers_diag = [(1, elt) for elt in birth_death] # Use subplots to display diagram and density side by side - fig, axes = plot.subplots(nrows=1, ncols=2, figsize=(12, 5)) + fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(12, 5)) gudhi.plot_persistence_diagram(persistence=pers_diag, axes=axes[0]) gudhi.plot_persistence_density(persistence=pers_diag, dimension=1, legend=True, axes=axes[1]) - plot.show() + plt.show() -- cgit v1.2.3 From b2c1cf839080efa43835d7b0fdcd6a38f6808255 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Wed, 26 Feb 2020 10:20:00 +0100 Subject: Fix #229 incomplete citation in nerve_GIC python documentation --- src/python/gudhi/nerve_gic.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/python') diff --git a/src/python/gudhi/nerve_gic.pyx b/src/python/gudhi/nerve_gic.pyx index 382e71c5..45cc8eba 100644 --- a/src/python/gudhi/nerve_gic.pyx +++ b/src/python/gudhi/nerve_gic.pyx @@ -187,7 +187,7 @@ cdef class CoverComplex: def set_automatic_resolution(self): """Computes the optimal length of intervals (i.e. the smallest interval - length avoiding discretization artifacts—see :cite:`Carriere17c`) for a + length avoiding discretization artifacts - see :cite:`Carriere17c`) for a functional cover. :rtype: double @@ -288,7 +288,7 @@ cdef class CoverComplex: def set_graph_from_automatic_rips(self, N=100): """Creates a graph G from a Rips complex whose threshold value is - automatically tuned with subsampling—see. + automatically tuned with subsampling - see :cite:`Carriere17c`. :param N: Number of subsampling iteration (the default reasonable value is 100, but there is no guarantee on how to choose it). -- cgit v1.2.3 From efae8ff48c6b6e4d29afea753b7a1ddee0925ad4 Mon Sep 17 00:00:00 2001 From: tlacombe Date: Tue, 3 Mar 2020 16:44:58 +0100 Subject: handle numpy array, should now adapt the doc --- src/python/gudhi/persistence_graphical_tools.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/python') diff --git a/src/python/gudhi/persistence_graphical_tools.py b/src/python/gudhi/persistence_graphical_tools.py index 8ddfdba8..43776fc6 100644 --- a/src/python/gudhi/persistence_graphical_tools.py +++ b/src/python/gudhi/persistence_graphical_tools.py @@ -45,6 +45,13 @@ def __min_birth_max_death(persistence, band=0.0): return (min_birth, max_death) +def _array_handler(a): + if isinstance(a, np.ndarray): + return [[0, x] for x in a] + else: + return a + + def plot_persistence_barcode( persistence=[], persistence_file="", @@ -95,6 +102,9 @@ def plot_persistence_barcode( plt.rc('text', usetex=True) plt.rc('font', family='serif') + + persistence = _array_handler(persistence) + if persistence_file != "": if path.isfile(persistence_file): # Reset persistence @@ -237,6 +247,7 @@ def plot_persistence_diagram( plt.rc('text', usetex=True) plt.rc('font', family='serif') + persistence = _array_handler(persistence) if persistence_file != "": if path.isfile(persistence_file): @@ -399,6 +410,7 @@ def plot_persistence_density( plt.rc('text', usetex=True) plt.rc('font', family='serif') + persistence = _array_handler(persistence) if persistence_file != "": if dimension is None: -- cgit v1.2.3 From 4f4030e9f9e0215c2d1f2431c02cd9270bba2699 Mon Sep 17 00:00:00 2001 From: tlacombe Date: Tue, 3 Mar 2020 16:57:56 +0100 Subject: updated doc and example handling Nx2 numpy arrays --- src/python/doc/persistence_graphical_tools_sum.inc | 2 +- .../doc/persistence_graphical_tools_user.rst | 12 +++++++++++ src/python/gudhi/persistence_graphical_tools.py | 25 ++++++++++++++++------ 3 files changed, 32 insertions(+), 7 deletions(-) (limited to 'src/python') diff --git a/src/python/doc/persistence_graphical_tools_sum.inc b/src/python/doc/persistence_graphical_tools_sum.inc index 2ddaccfc..ef376802 100644 --- a/src/python/doc/persistence_graphical_tools_sum.inc +++ b/src/python/doc/persistence_graphical_tools_sum.inc @@ -2,7 +2,7 @@ :widths: 30 50 20 +-----------------------------------------------------------------+-----------------------------------------------------------------------+-----------------------------------------------+ - | .. figure:: | These graphical tools comes on top of persistence results and allows | :Author: Vincent Rouvreau | + | .. figure:: | These graphical tools comes on top of persistence results and allows | :Author: Vincent Rouvreau, Theo Lacombe | | img/graphical_tools_representation.png | the user to display easily persistence barcode, diagram or density. | | | | | :Introduced in: GUDHI 2.0.0 | | | Note that these functions return the matplotlib axis, allowing | | diff --git a/src/python/doc/persistence_graphical_tools_user.rst b/src/python/doc/persistence_graphical_tools_user.rst index ff51604e..91e52703 100644 --- a/src/python/doc/persistence_graphical_tools_user.rst +++ b/src/python/doc/persistence_graphical_tools_user.rst @@ -57,6 +57,18 @@ This function can display the persistence result as a diagram: ax.set_aspect("equal") # forces to be square shaped plt.show() +Note that (as barcode and density) it can also take a simple `np.array` +of shape (N x 2) encoding a persistence diagram (in a given dimension). + +.. plot:: + :include-source: + + import matplotlib.pyplot as plt + import gudhi + import numpy as np + d = np.array([[0, 1], [1, 2], [1, np.inf]]) + gudhi.plot_persistence_diagram(d) + plt.show() Persistence density ------------------- diff --git a/src/python/gudhi/persistence_graphical_tools.py b/src/python/gudhi/persistence_graphical_tools.py index 43776fc6..48e26432 100644 --- a/src/python/gudhi/persistence_graphical_tools.py +++ b/src/python/gudhi/persistence_graphical_tools.py @@ -15,7 +15,7 @@ import numpy as np from gudhi.reader_utils import read_persistence_intervals_in_dimension from gudhi.reader_utils import read_persistence_intervals_grouped_by_dimension -__author__ = "Vincent Rouvreau, Bertrand Michel" +__author__ = "Vincent Rouvreau, Bertrand Michel, Theo Lacombe" __copyright__ = "Copyright (C) 2016 Inria" __license__ = "MIT" @@ -46,6 +46,11 @@ def __min_birth_max_death(persistence, band=0.0): def _array_handler(a): + ''' + :param a: if array, assumes it is a (n x 2) np.array and return a + persistence-compatible list (padding with 0), so that the + plot can be performed seamlessly. + ''' if isinstance(a, np.ndarray): return [[0, x] for x in a] else: @@ -65,9 +70,12 @@ def plot_persistence_barcode( fontsize=16, ): """This function plots the persistence bar code from persistence values list + , a np.array of shape (N x 2) (representing a diagram + in a single homology dimension), or from a :doc:`persistence file `. - :param persistence: Persistence intervals values list grouped by dimension. + :param persistence: Persistence intervals values list grouped by dimension, + or np.array of shape (N x 2). :type persistence: list of tuples(dimension, tuple(birth, death)). :param persistence_file: A :doc:`persistence file ` style name (reset persistence if both are set). @@ -206,9 +214,11 @@ def plot_persistence_diagram( greyblock=True ): """This function plots the persistence diagram from persistence values - list or from a :doc:`persistence file `. + list, a np.array of shape (N x 2) representing a diagram in a single + homology dimension, or from a :doc:`persistence file `. - :param persistence: Persistence intervals values list grouped by dimension. + :param persistence: Persistence intervals values list grouped by dimension, + or np.array of shape (N x 2). :type persistence: list of tuples(dimension, tuple(birth, death)). :param persistence_file: A :doc:`persistence file ` style name (reset persistence if both are set). @@ -356,12 +366,15 @@ def plot_persistence_density( greyblock=True ): """This function plots the persistence density from persistence - values list or from a :doc:`persistence file `. Be + values list, np.array of shape (N x 2) representing a diagram + in a single homology dimension, + or from a :doc:`persistence file `. Be aware that this function does not distinguish the dimension, it is up to you to select the required one. This function also does not handle degenerate data set (scipy correlation matrix inversion can fail). - :param persistence: Persistence intervals values list grouped by dimension. + :param persistence: Persistence intervals values list grouped by dimension, + or np.array of shape (N x 2). :type persistence: list of tuples(dimension, tuple(birth, death)). :param persistence_file: A :doc:`persistence file ` style name (reset persistence if both are set). -- cgit v1.2.3 From e1dbf6da118615e20d2b642df98b7d3df7cfd8c7 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Thu, 5 Mar 2020 10:16:51 +0100 Subject: Remove travis and use appveyor for OSx. Fix parallel test by setting tests dependencies --- .github/build-requirements.txt | 5 ++ .github/test-requirements.txt | 8 +++ .travis.yml | 78 ---------------------- Dockerfile_for_circleci_image | 22 ++---- azure-pipelines.yml | 44 ++++++++++++ src/Alpha_complex/example/CMakeLists.txt | 6 +- src/Alpha_complex/utilities/CMakeLists.txt | 12 +++- .../utilities/CMakeLists.txt | 10 ++- .../utilities/persistence_heat_maps/CMakeLists.txt | 19 ++++-- .../utilities/persistence_intervals/CMakeLists.txt | 7 +- .../persistence_landscapes/CMakeLists.txt | 8 +-- .../persistence_landscapes_on_grid/CMakeLists.txt | 8 +-- .../utilities/persistence_vectors/CMakeLists.txt | 8 +-- src/Rips_complex/example/CMakeLists.txt | 8 +++ src/common/example/CMakeLists.txt | 1 + src/python/CMakeLists.txt | 2 +- 16 files changed, 128 insertions(+), 118 deletions(-) create mode 100644 .github/build-requirements.txt create mode 100644 .github/test-requirements.txt delete mode 100644 .travis.yml create mode 100644 azure-pipelines.yml (limited to 'src/python') diff --git a/.github/build-requirements.txt b/.github/build-requirements.txt new file mode 100644 index 00000000..7de60d23 --- /dev/null +++ b/.github/build-requirements.txt @@ -0,0 +1,5 @@ +setuptools +wheel +numpy +Cython +pybind11 \ No newline at end of file diff --git a/.github/test-requirements.txt b/.github/test-requirements.txt new file mode 100644 index 00000000..bd03f98e --- /dev/null +++ b/.github/test-requirements.txt @@ -0,0 +1,8 @@ +pytest +sphinx +sphinxcontrib-bibtex +sphinx-paramlinks +matplotlib +scipy +scikit-learn +POT \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 8980be10..00000000 --- a/.travis.yml +++ /dev/null @@ -1,78 +0,0 @@ -language: cpp - -sudo: required - -git: - depth: 3 - -os: osx -osx_image: xcode10.2 -compiler: clang - -matrix: - include: - - env: - # 1. Only examples and associated tests - - CMAKE_EXAMPLE='ON' CMAKE_TEST='OFF' CMAKE_UTILITIES='OFF' CMAKE_PYTHON='OFF' MAKE_TARGET='all' CTEST_COMMAND='ctest --output-on-failure' - - env: - # 2. Only unitary tests - - CMAKE_EXAMPLE='OFF' CMAKE_TEST='ON' CMAKE_UTILITIES='OFF' CMAKE_PYTHON='OFF' MAKE_TARGET='all' CTEST_COMMAND='ctest --output-on-failure' - - env: - # 3. Only utilities and associated tests - - CMAKE_EXAMPLE='OFF' CMAKE_TEST='OFF' CMAKE_UTILITIES='ON' CMAKE_PYTHON='OFF' MAKE_TARGET='all' CTEST_COMMAND='ctest --output-on-failure' - - env: - # 4. Only doxygen documentation - - CMAKE_EXAMPLE='OFF' CMAKE_TEST='OFF' CMAKE_UTILITIES='OFF' CMAKE_PYTHON='OFF' MAKE_TARGET='doxygen' CTEST_COMMAND='echo No tests for doxygen target' - - env: - # 5. Only Python, associated tests and sphinx documentation - # $ which python3 => /usr/local/bin/python3 - # cmake => -- Found PythonInterp: /usr/local/bin/python3 (found version "3.7.5") - # In python3-sphinx-build.py, print(sys.executable) => /usr/local/opt/python/bin/python3.7 ??? - # should be : MAKE_TARGET='all sphinx' CTEST_COMMAND='ctest --output-on-failure' - - CMAKE_EXAMPLE='OFF' CMAKE_TEST='OFF' CMAKE_UTILITIES='OFF' CMAKE_PYTHON='ON' MAKE_TARGET='all' CTEST_COMMAND='ctest --output-on-failure -E sphinx' - -cache: - directories: - - $HOME/.cache/pip - - $HOME/Library/Caches/Homebrew - -before_install: - - brew update && brew unlink python@2 && brew upgrade python - -addons: - homebrew: - packages: - - python3 - - cmake - - graphviz - - doxygen - - boost - - eigen - - gmp - - mpfr - - tbb - - cgal - -before_cache: - - rm -f $HOME/.cache/pip/log/debug.log - - brew cleanup - -# When installing through libcgal-dev apt, CMake Error at CGAL Exports.cmake The imported target "CGAL::CGAL Qt5" references the file -install: - - python3 -m pip install --upgrade pip setuptools wheel - - python3 -m pip install --user pytest Cython sphinx sphinxcontrib-bibtex sphinx-paramlinks matplotlib numpy scipy scikit-learn - - python3 -m pip install --user POT pybind11 - -script: - - rm -rf build - - mkdir -p build - - cd build - - cmake -DCMAKE_BUILD_TYPE=Release -DWITH_GUDHI_EXAMPLE=${CMAKE_EXAMPLE} -DWITH_GUDHI_TEST=${CMAKE_TEST} -DWITH_GUDHI_UTILITIES=${CMAKE_UTILITIES} -DWITH_GUDHI_PYTHON=${CMAKE_PYTHON} -DUSER_VERSION_DIR=version -DPython_ADDITIONAL_VERSIONS=3 .. - - make ${MAKE_TARGET} - - ${CTEST_COMMAND} - - cd .. - -notifications: - email: - on_success: change # default: always - on_failure: always # default: always diff --git a/Dockerfile_for_circleci_image b/Dockerfile_for_circleci_image index ebd2f366..cca93f0c 100644 --- a/Dockerfile_for_circleci_image +++ b/Dockerfile_for_circleci_image @@ -42,24 +42,16 @@ RUN apt-get install -y make \ locales \ python3 \ python3-pip \ - python3-pytest \ python3-tk \ - python3-pybind11 \ libfreetype6-dev \ - pkg-config + pkg-config \ + curl -RUN pip3 install \ - setuptools \ - numpy \ - matplotlib \ - scipy \ - Cython \ - POT \ - scikit-learn \ - sphinx \ - sphinx-paramlinks \ - sphinxcontrib-bibtex \ - tensorflow +ADD .github/build-requirements.txt / +ADD .github/test-requirements.txt / + +RUN pip3 install -r build-requirements.txt +RUN pip3 install -r test-requirements.txt # apt clean up RUN apt autoremove && rm -rf /var/lib/apt/lists/* diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 00000000..77e0ac88 --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,44 @@ +trigger: + batch: true + branches: + include: + - '*' # All branches + +jobs: + + - job: 'Test' + displayName: "Build and test" + timeoutInMinutes: 0 + cancelTimeoutInMinutes: 60 + + strategy: + matrix: + macOSrelease: + imageName: 'macos-10.14' + CMakeBuildType: Release + customInstallation: 'brew update && brew install graphviz doxygen boost eigen gmp mpfr tbb cgal' + + pool: + vmImage: $(imageName) + + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: '3.7' + architecture: 'x64' + + - script: | + $(customInstallation) + git submodule update --init + python -m pip install --upgrade pip + python -m pip install --user -r .github/build-requirements.txt + python -m pip install --user -r .github/test-requirements.txt + displayName: 'Install build dependencies' + - script: | + mkdir build + cd build + cmake -DCMAKE_BUILD_TYPE:STRING=$(CMakeBuildType) -DWITH_GUDHI_TEST=ON -DWITH_GUDHI_UTILITIES=ON -DWITH_GUDHI_PYTHON=ON -DPython_ADDITIONAL_VERSIONS=3 .. + make + make doxygen + ctest -j 8 --output-on-failure -E sphinx # remove sphinx build as it fails + displayName: 'Build, test and documentation generation' diff --git a/src/Alpha_complex/example/CMakeLists.txt b/src/Alpha_complex/example/CMakeLists.txt index b0337934..2eecd50c 100644 --- a/src/Alpha_complex/example/CMakeLists.txt +++ b/src/Alpha_complex/example/CMakeLists.txt @@ -32,14 +32,18 @@ if (DIFF_PATH) add_test(Alpha_complex_example_from_off_60_diff_files ${DIFF_PATH} ${CMAKE_CURRENT_BINARY_DIR}/alphaoffreader_result_60.txt ${CMAKE_CURRENT_BINARY_DIR}/alphaoffreader_for_doc_60.txt) + set_tests_properties(Alpha_complex_example_from_off_60_diff_files PROPERTIES DEPENDS Alpha_complex_example_from_off_60) add_test(Alpha_complex_example_from_off_32_diff_files ${DIFF_PATH} ${CMAKE_CURRENT_BINARY_DIR}/alphaoffreader_result_32.txt ${CMAKE_CURRENT_BINARY_DIR}/alphaoffreader_for_doc_32.txt) + set_tests_properties(Alpha_complex_example_from_off_32_diff_files PROPERTIES DEPENDS Alpha_complex_example_from_off_32) add_test(Alpha_complex_example_fast_from_off_60_diff_files ${DIFF_PATH} ${CMAKE_CURRENT_BINARY_DIR}/fastalphaoffreader_result_60.txt ${CMAKE_CURRENT_BINARY_DIR}/alphaoffreader_for_doc_60.txt) + set_tests_properties(Alpha_complex_example_fast_from_off_60_diff_files PROPERTIES DEPENDS Alpha_complex_example_fast_from_off_60) add_test(Alpha_complex_example_fast_from_off_32_diff_files ${DIFF_PATH} ${CMAKE_CURRENT_BINARY_DIR}/fastalphaoffreader_result_32.txt ${CMAKE_CURRENT_BINARY_DIR}/alphaoffreader_for_doc_32.txt) - endif() + set_tests_properties(Alpha_complex_example_fast_from_off_32_diff_files PROPERTIES DEPENDS Alpha_complex_example_fast_from_off_32) +endif() add_executable ( Alpha_complex_example_weighted_3d_from_points Weighted_alpha_complex_3d_from_points.cpp ) target_link_libraries(Alpha_complex_example_weighted_3d_from_points ${CGAL_LIBRARY}) diff --git a/src/Alpha_complex/utilities/CMakeLists.txt b/src/Alpha_complex/utilities/CMakeLists.txt index a3b0cc24..2ffbdde0 100644 --- a/src/Alpha_complex/utilities/CMakeLists.txt +++ b/src/Alpha_complex/utilities/CMakeLists.txt @@ -16,8 +16,14 @@ if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0) if (DIFF_PATH) add_test(Alpha_complex_utilities_diff_exact_alpha_complex ${DIFF_PATH} "exact.pers" "safe.pers") + set_tests_properties(Alpha_complex_utilities_diff_exact_alpha_complex PROPERTIES DEPENDS + "Alpha_complex_utilities_exact_alpha_complex_persistence;Alpha_complex_utilities_safe_alpha_complex_persistence") + add_test(Alpha_complex_utilities_diff_fast_alpha_complex ${DIFF_PATH} "fast.pers" "safe.pers") + set_tests_properties(Alpha_complex_utilities_diff_fast_alpha_complex PROPERTIES DEPENDS + "Alpha_complex_utilities_fast_alpha_complex_persistence;Alpha_complex_utilities_safe_alpha_complex_persistence") + endif() install(TARGETS alpha_complex_persistence DESTINATION bin) @@ -36,15 +42,19 @@ if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0) "${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off" "-p" "2" "-m" "0.45" "-o" "exact_3d.pers" "-e") - add_test(NAME Alpha_complex_utilities_safe_alpha_complex_3d COMMAND $ + add_test(NAME Alpha_complex_utilities_fast_alpha_complex_3d COMMAND $ "${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off" "-p" "2" "-m" "0.45" "-o" "fast_3d.pers" "-f") if (DIFF_PATH) add_test(Alpha_complex_utilities_diff_exact_alpha_complex_3d ${DIFF_PATH} "exact_3d.pers" "safe_3d.pers") + set_tests_properties(Alpha_complex_utilities_diff_exact_alpha_complex_3d PROPERTIES DEPENDS + "Alpha_complex_utilities_exact_alpha_complex_3d;Alpha_complex_utilities_alpha_complex_3d") add_test(Alpha_complex_utilities_diff_fast_alpha_complex_3d ${DIFF_PATH} "fast_3d.pers" "safe_3d.pers") + set_tests_properties(Alpha_complex_utilities_diff_fast_alpha_complex_3d PROPERTIES DEPENDS + "Alpha_complex_utilities_fast_alpha_complex_3d;Alpha_complex_utilities_alpha_complex_3d") endif() add_test(NAME Alpha_complex_utilities_periodic_alpha_complex_3d_persistence COMMAND $ diff --git a/src/Persistence_representations/utilities/CMakeLists.txt b/src/Persistence_representations/utilities/CMakeLists.txt index fc51b1d6..85633b7b 100644 --- a/src/Persistence_representations/utilities/CMakeLists.txt +++ b/src/Persistence_representations/utilities/CMakeLists.txt @@ -14,7 +14,7 @@ function(add_persistence_representation_creation_utility creation_utility) install(TARGETS ${creation_utility} DESTINATION bin) endfunction(add_persistence_representation_creation_utility) -function(add_persistence_representation_plot_utility plot_utility tool_extension) +function(add_persistence_representation_plot_utility creation_utility plot_utility tool_extension) add_executable ( ${plot_utility} ${plot_utility}.cpp ) # as the function is called in a subdirectory level, need to '../' to find persistence heat maps files @@ -22,17 +22,21 @@ function(add_persistence_representation_plot_utility plot_utility tool_extension "${CMAKE_CURRENT_BINARY_DIR}/../first.pers${tool_extension}") #add_test(NAME Persistence_representation_utilities_${plot_utility}_second COMMAND $ # "${CMAKE_CURRENT_BINARY_DIR}/../second.pers${tool_extension}") + set_tests_properties(Persistence_representation_utilities_${plot_utility}_first PROPERTIES DEPENDS + Persistence_representation_utilities_${creation_utility}) if(GNUPLOT_PATH) add_test(NAME Persistence_representation_utilities_${plot_utility}_first_gnuplot COMMAND ${GNUPLOT_PATH} "-e" "load '${CMAKE_CURRENT_BINARY_DIR}/../first.pers${tool_extension}_GnuplotScript'") #add_test(NAME Persistence_representation_utilities_${plot_utility}_second_gnuplot COMMAND ${GNUPLOT_PATH} # "-e" "load '${CMAKE_CURRENT_BINARY_DIR}/../second.pers${tool_extension}_GnuplotScript'") + set_tests_properties(Persistence_representation_utilities_${plot_utility}_first_gnuplot PROPERTIES DEPENDS + Persistence_representation_utilities_${plot_utility}_first) endif() install(TARGETS ${plot_utility} DESTINATION bin) endfunction(add_persistence_representation_plot_utility) -function(add_persistence_representation_function_utility function_utility tool_extension) +function(add_persistence_representation_function_utility creation_utility function_utility tool_extension) add_executable ( ${function_utility} ${function_utility}.cpp ) # ARGV2 is an optional argument @@ -48,6 +52,8 @@ function(add_persistence_representation_function_utility function_utility tool_e "${CMAKE_CURRENT_BINARY_DIR}/../first.pers${tool_extension}" "${CMAKE_CURRENT_BINARY_DIR}/../second.pers${tool_extension}") endif() + set_tests_properties(Persistence_representation_utilities_${function_utility} PROPERTIES DEPENDS + Persistence_representation_utilities_${creation_utility}) install(TARGETS ${function_utility} DESTINATION bin) endfunction(add_persistence_representation_function_utility) diff --git a/src/Persistence_representations/utilities/persistence_heat_maps/CMakeLists.txt b/src/Persistence_representations/utilities/persistence_heat_maps/CMakeLists.txt index 89ef232f..e4c471c2 100644 --- a/src/Persistence_representations/utilities/persistence_heat_maps/CMakeLists.txt +++ b/src/Persistence_representations/utilities/persistence_heat_maps/CMakeLists.txt @@ -2,13 +2,24 @@ project(Persistence_representations_heat_maps_utilities) add_persistence_representation_creation_utility(create_pssk "10" "-1" "-1" "4" "-1") add_persistence_representation_creation_utility(create_p_h_m_weighted_by_arctan_of_their_persistence "10" "-1" "-1" "4" "-1") + add_persistence_representation_creation_utility(create_p_h_m_weighted_by_distance_from_diagonal "10" "-1" "-1" "4" "-1") +# Tests output the same file +set_tests_properties(Persistence_representation_utilities_create_p_h_m_weighted_by_distance_from_diagonal PROPERTIES DEPENDS + Persistence_representation_utilities_create_p_h_m_weighted_by_arctan_of_their_persistence) + add_persistence_representation_creation_utility(create_p_h_m_weighted_by_squared_diag_distance "10" "-1" "-1" "4" "-1") +# Tests output the same file +set_tests_properties(Persistence_representation_utilities_create_p_h_m_weighted_by_squared_diag_distance PROPERTIES DEPENDS + Persistence_representation_utilities_create_p_h_m_weighted_by_distance_from_diagonal) + # Need to set grid min and max for further average, distance and scalar_product add_persistence_representation_creation_utility(create_persistence_heat_maps "10" "0" "35" "10" "-1") +set_tests_properties(Persistence_representation_utilities_create_persistence_heat_maps PROPERTIES DEPENDS + Persistence_representation_utilities_create_p_h_m_weighted_by_squared_diag_distance) -add_persistence_representation_plot_utility(plot_persistence_heat_map ".mps") +add_persistence_representation_plot_utility(create_persistence_heat_maps plot_persistence_heat_map ".mps") -add_persistence_representation_function_utility(average_persistence_heat_maps ".mps") -add_persistence_representation_function_utility(compute_distance_of_persistence_heat_maps ".mps" "1") -add_persistence_representation_function_utility(compute_scalar_product_of_persistence_heat_maps ".mps") +add_persistence_representation_function_utility(create_persistence_heat_maps average_persistence_heat_maps ".mps") +add_persistence_representation_function_utility(create_persistence_heat_maps compute_distance_of_persistence_heat_maps ".mps" "1") +add_persistence_representation_function_utility(create_persistence_heat_maps compute_scalar_product_of_persistence_heat_maps ".mps") diff --git a/src/Persistence_representations/utilities/persistence_intervals/CMakeLists.txt b/src/Persistence_representations/utilities/persistence_intervals/CMakeLists.txt index a025183e..118c1e9b 100644 --- a/src/Persistence_representations/utilities/persistence_intervals/CMakeLists.txt +++ b/src/Persistence_representations/utilities/persistence_intervals/CMakeLists.txt @@ -3,17 +3,16 @@ project(Persistence_representations_intervals_utilities) add_executable ( plot_histogram_of_intervals_lengths plot_histogram_of_intervals_lengths.cpp ) -add_test(NAME plot_histogram_of_intervals_lengths COMMAND $ +add_test(NAME Persistence_representation_utilities_plot_histogram_of_intervals_lengths COMMAND $ "${CMAKE_CURRENT_BINARY_DIR}/../first.pers" "-1") install(TARGETS plot_histogram_of_intervals_lengths DESTINATION bin) -add_persistence_representation_plot_utility(plot_persistence_intervals "") -add_persistence_representation_plot_utility(plot_persistence_Betti_numbers "") +add_persistence_representation_plot_utility(plot_histogram_of_intervals_lengths plot_persistence_intervals "") +add_persistence_representation_plot_utility(plot_histogram_of_intervals_lengths plot_persistence_Betti_numbers "") add_persistence_representation_creation_utility(compute_birth_death_range_in_persistence_diagram "-1") - add_executable ( compute_number_of_dominant_intervals compute_number_of_dominant_intervals.cpp ) add_test(NAME Persistence_representation_utilities_compute_number_of_dominant_intervals COMMAND $ diff --git a/src/Persistence_representations/utilities/persistence_landscapes/CMakeLists.txt b/src/Persistence_representations/utilities/persistence_landscapes/CMakeLists.txt index 6b24d032..4df84d36 100644 --- a/src/Persistence_representations/utilities/persistence_landscapes/CMakeLists.txt +++ b/src/Persistence_representations/utilities/persistence_landscapes/CMakeLists.txt @@ -2,8 +2,8 @@ project(Persistence_representations_landscapes_utilities) add_persistence_representation_creation_utility(create_landscapes "-1") -add_persistence_representation_plot_utility(plot_landscapes ".land") +add_persistence_representation_plot_utility(create_landscapes plot_landscapes ".land") -add_persistence_representation_function_utility(average_landscapes ".land") -add_persistence_representation_function_utility(compute_distance_of_landscapes ".land" "1") -add_persistence_representation_function_utility(compute_scalar_product_of_landscapes ".land") +add_persistence_representation_function_utility(create_landscapes average_landscapes ".land") +add_persistence_representation_function_utility(create_landscapes compute_distance_of_landscapes ".land" "1") +add_persistence_representation_function_utility(create_landscapes compute_scalar_product_of_landscapes ".land") diff --git a/src/Persistence_representations/utilities/persistence_landscapes_on_grid/CMakeLists.txt b/src/Persistence_representations/utilities/persistence_landscapes_on_grid/CMakeLists.txt index 36f3196b..8cd965f1 100644 --- a/src/Persistence_representations/utilities/persistence_landscapes_on_grid/CMakeLists.txt +++ b/src/Persistence_representations/utilities/persistence_landscapes_on_grid/CMakeLists.txt @@ -3,8 +3,8 @@ project(Persistence_representations_lanscapes_on_grid_utilities) # Need to set grid min and max for further average, distance and scalar_product add_persistence_representation_creation_utility(create_landscapes_on_grid "100" "0" "35" "-1") -add_persistence_representation_plot_utility(plot_landscapes_on_grid ".g_land") +add_persistence_representation_plot_utility(create_landscapes_on_grid plot_landscapes_on_grid ".g_land") -add_persistence_representation_function_utility(average_landscapes_on_grid ".g_land") -add_persistence_representation_function_utility(compute_distance_of_landscapes_on_grid ".g_land" "1") -add_persistence_representation_function_utility(compute_scalar_product_of_landscapes_on_grid ".g_land") +add_persistence_representation_function_utility(create_landscapes_on_grid average_landscapes_on_grid ".g_land") +add_persistence_representation_function_utility(create_landscapes_on_grid compute_distance_of_landscapes_on_grid ".g_land" "1") +add_persistence_representation_function_utility(create_landscapes_on_grid compute_scalar_product_of_landscapes_on_grid ".g_land") diff --git a/src/Persistence_representations/utilities/persistence_vectors/CMakeLists.txt b/src/Persistence_representations/utilities/persistence_vectors/CMakeLists.txt index bc982094..5b22ca84 100644 --- a/src/Persistence_representations/utilities/persistence_vectors/CMakeLists.txt +++ b/src/Persistence_representations/utilities/persistence_vectors/CMakeLists.txt @@ -2,8 +2,8 @@ project(Persistence_vectors_utilities) add_persistence_representation_creation_utility(create_persistence_vectors "-1") -add_persistence_representation_plot_utility(plot_persistence_vectors ".vect") +add_persistence_representation_plot_utility(create_persistence_vectors plot_persistence_vectors ".vect") -add_persistence_representation_function_utility(average_persistence_vectors ".vect") -add_persistence_representation_function_utility(compute_distance_of_persistence_vectors ".vect" "1") -add_persistence_representation_function_utility(compute_scalar_product_of_persistence_vectors ".vect") +add_persistence_representation_function_utility(create_persistence_vectors average_persistence_vectors ".vect") +add_persistence_representation_function_utility(create_persistence_vectors compute_distance_of_persistence_vectors ".vect" "1") +add_persistence_representation_function_utility(create_persistence_vectors compute_scalar_product_of_persistence_vectors ".vect") diff --git a/src/Rips_complex/example/CMakeLists.txt b/src/Rips_complex/example/CMakeLists.txt index e7772bdb..244a93ec 100644 --- a/src/Rips_complex/example/CMakeLists.txt +++ b/src/Rips_complex/example/CMakeLists.txt @@ -53,15 +53,23 @@ if (DIFF_PATH) add_test(Rips_complex_example_from_off_doc_12_1_diff_files ${DIFF_PATH} ${CMAKE_CURRENT_BINARY_DIR}/ripsoffreader_result_12_1.txt ${CMAKE_CURRENT_BINARY_DIR}/one_skeleton_rips_for_doc.txt) + set_tests_properties(Rips_complex_example_from_off_doc_12_1_diff_files PROPERTIES DEPENDS Rips_complex_example_from_off_doc_12_1) + add_test(Rips_complex_example_from_off_doc_12_3_diff_files ${DIFF_PATH} ${CMAKE_CURRENT_BINARY_DIR}/ripsoffreader_result_12_3.txt ${CMAKE_CURRENT_BINARY_DIR}/full_skeleton_rips_for_doc.txt) + set_tests_properties(Rips_complex_example_from_off_doc_12_3_diff_files PROPERTIES DEPENDS Rips_complex_example_from_off_doc_12_3) + add_test(Rips_complex_example_from_csv_distance_matrix_doc_12_1_diff_files ${DIFF_PATH} ${CMAKE_CURRENT_BINARY_DIR}/ripscsvreader_result_12_1.txt ${CMAKE_CURRENT_BINARY_DIR}/one_skeleton_rips_for_doc.txt) + set_tests_properties(Rips_complex_example_from_csv_distance_matrix_doc_12_1_diff_files PROPERTIES DEPENDS Rips_complex_example_from_csv_distance_matrix_doc_12_1) + add_test(Rips_complex_example_from_csv_distance_matrix_doc_12_3_diff_files ${DIFF_PATH} ${CMAKE_CURRENT_BINARY_DIR}/ripscsvreader_result_12_3.txt ${CMAKE_CURRENT_BINARY_DIR}/full_skeleton_rips_for_doc.txt) + set_tests_properties(Rips_complex_example_from_csv_distance_matrix_doc_12_3_diff_files PROPERTIES DEPENDS Rips_complex_example_from_csv_distance_matrix_doc_12_3) + endif() install(TARGETS Rips_complex_example_from_off DESTINATION bin) diff --git a/src/common/example/CMakeLists.txt b/src/common/example/CMakeLists.txt index 583a0027..fa8eb98c 100644 --- a/src/common/example/CMakeLists.txt +++ b/src/common/example/CMakeLists.txt @@ -12,6 +12,7 @@ if (DIFF_PATH) add_test(Common_example_vector_double_off_reader_diff_files ${DIFF_PATH} ${CMAKE_CURRENT_BINARY_DIR}/vectordoubleoffreader_result.txt ${CMAKE_CURRENT_BINARY_DIR}/alphacomplexdoc.off.txt) + set_tests_properties(Common_example_vector_double_off_reader_diff_files PROPERTIES DEPENDS Common_example_vector_double_off_reader) endif() if(NOT CGAL_VERSION VERSION_LESS 4.11.0) diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index 090a7446..20e72a5f 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -181,7 +181,7 @@ if(PYTHONINTERP_FOUND) set(GUDHI_PYTHON_LIBRARY_DIRS "${GUDHI_PYTHON_LIBRARY_DIRS}'${MPFR_LIBRARIES_DIR}', ") message("** Add mpfr ${MPFR_LIBRARIES}") endif(MPFR_FOUND) -endif(CGAL_FOUND) + endif(CGAL_FOUND) # Specific for Mac if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") -- cgit v1.2.3 From 05985743182a5e7d462a6a8b872b92c9b8a90404 Mon Sep 17 00:00:00 2001 From: Théo Lacombe Date: Thu, 5 Mar 2020 11:31:47 +0100 Subject: Update src/python/gudhi/persistence_graphical_tools.py Co-Authored-By: Vincent Rouvreau <10407034+VincentRouvreau@users.noreply.github.com> --- src/python/gudhi/persistence_graphical_tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/python') diff --git a/src/python/gudhi/persistence_graphical_tools.py b/src/python/gudhi/persistence_graphical_tools.py index 48e26432..c9af88f5 100644 --- a/src/python/gudhi/persistence_graphical_tools.py +++ b/src/python/gudhi/persistence_graphical_tools.py @@ -51,7 +51,7 @@ def _array_handler(a): persistence-compatible list (padding with 0), so that the plot can be performed seamlessly. ''' - if isinstance(a, np.ndarray): + if isinstance(a[0][1], np.float64) or isinstance(a[0][1], float): return [[0, x] for x in a] else: return a -- cgit v1.2.3 From eccfa153efe660662be945134115f7634c27335d Mon Sep 17 00:00:00 2001 From: tlacombe Date: Thu, 5 Mar 2020 15:32:09 +0100 Subject: updated doc --- src/python/gudhi/persistence_graphical_tools.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'src/python') diff --git a/src/python/gudhi/persistence_graphical_tools.py b/src/python/gudhi/persistence_graphical_tools.py index c9af88f5..6fd854ff 100644 --- a/src/python/gudhi/persistence_graphical_tools.py +++ b/src/python/gudhi/persistence_graphical_tools.py @@ -74,9 +74,8 @@ def plot_persistence_barcode( in a single homology dimension), or from a :doc:`persistence file `. - :param persistence: Persistence intervals values list grouped by dimension, - or np.array of shape (N x 2). - :type persistence: list of tuples(dimension, tuple(birth, death)). + :param persistence: Persistence intervals values list. Can be grouped by dimension or not. + :type persistence: an array of (dimension, array of (birth, death)) or an array of (birth, death). :param persistence_file: A :doc:`persistence file ` style name (reset persistence if both are set). :type persistence_file: string @@ -217,9 +216,8 @@ def plot_persistence_diagram( list, a np.array of shape (N x 2) representing a diagram in a single homology dimension, or from a :doc:`persistence file `. - :param persistence: Persistence intervals values list grouped by dimension, - or np.array of shape (N x 2). - :type persistence: list of tuples(dimension, tuple(birth, death)). + :param persistence: Persistence intervals values list. Can be grouped by dimension or not. + :type persistence: an array of (dimension, array of (birth, death)) or an array of (birth, death). :param persistence_file: A :doc:`persistence file ` style name (reset persistence if both are set). :type persistence_file: string @@ -373,9 +371,10 @@ def plot_persistence_density( up to you to select the required one. This function also does not handle degenerate data set (scipy correlation matrix inversion can fail). - :param persistence: Persistence intervals values list grouped by dimension, - or np.array of shape (N x 2). - :type persistence: list of tuples(dimension, tuple(birth, death)). + :param persistence: Persistence intervals values list. + Can be grouped by dimension or not. + :type persistence: an array of (dimension, array of (birth, death)) + or an array of (birth, death). :param persistence_file: A :doc:`persistence file ` style name (reset persistence if both are set). :type persistence_file: string -- cgit v1.2.3 From 7789744d5d5972ef2d6218296a7b8a0a05337679 Mon Sep 17 00:00:00 2001 From: tlacombe Date: Fri, 6 Mar 2020 13:31:05 +0100 Subject: set greyblock to False by default in density --- src/python/gudhi/persistence_graphical_tools.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/python') diff --git a/src/python/gudhi/persistence_graphical_tools.py b/src/python/gudhi/persistence_graphical_tools.py index 6fd854ff..8c38b684 100644 --- a/src/python/gudhi/persistence_graphical_tools.py +++ b/src/python/gudhi/persistence_graphical_tools.py @@ -361,7 +361,7 @@ def plot_persistence_density( legend=False, axes=None, fontsize=16, - greyblock=True + greyblock=False ): """This function plots the persistence density from persistence values list, np.array of shape (N x 2) representing a diagram @@ -410,7 +410,7 @@ def plot_persistence_density( :param fontsize: Fontsize to use in axis. :type fontsize: int :param greyblock: if we want to plot a grey patch on the lower half plane - for nicer rendering. Default True. + for nicer rendering. Default False. :type greyblock: boolean :returns: (`matplotlib.axes.Axes`): The axes on which the plot was drawn. """ -- cgit v1.2.3 From 5bc96fdf837e4acb80b1333b9db63ddf5802edc8 Mon Sep 17 00:00:00 2001 From: tlacombe Date: Mon, 9 Mar 2020 12:12:13 +0100 Subject: removed infty line plot in plot_diagram if no pts at infty --- src/python/gudhi/persistence_graphical_tools.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'src/python') diff --git a/src/python/gudhi/persistence_graphical_tools.py b/src/python/gudhi/persistence_graphical_tools.py index 8c38b684..cc3db467 100644 --- a/src/python/gudhi/persistence_graphical_tools.py +++ b/src/python/gudhi/persistence_graphical_tools.py @@ -296,17 +296,6 @@ def plot_persistence_diagram( axis_end = max_death + delta / 2 axis_start = min_birth - delta - # infinity line and text - axes.plot([axis_start, axis_end], [axis_start, axis_end], linewidth=1.0, color="k") - axes.plot([axis_start, axis_end], [infinity, infinity], linewidth=1.0, color="k", alpha=alpha) - # Infinity label - yt = axes.get_yticks() - yt = yt[np.where(yt < axis_end)] # to avoid ploting ticklabel higher than infinity - yt = np.append(yt, infinity) - ytl = ["%.3f" % e for e in yt] # to avoid float precision error - ytl[-1] = r'$+\infty$' - axes.set_yticks(yt) - axes.set_yticklabels(ytl) # bootstrap band if band > 0.0: x = np.linspace(axis_start, infinity, 1000) @@ -315,6 +304,7 @@ def plot_persistence_diagram( if greyblock: axes.add_patch(mpatches.Polygon([[axis_start, axis_start], [axis_end, axis_start], [axis_end, axis_end]], fill=True, color='lightgrey')) # Draw points in loop + pts_at_infty = False # Records presence of pts at infty for interval in reversed(persistence): if float(interval[1][1]) != float("inf"): # Finite death case @@ -325,10 +315,23 @@ def plot_persistence_diagram( color=colormap[interval[0]], ) else: + pts_at_infty = True # Infinite death case for diagram to be nicer axes.scatter( interval[1][0], infinity, alpha=alpha, color=colormap[interval[0]] ) + if pts_at_infty: + # infinity line and text + axes.plot([axis_start, axis_end], [axis_start, axis_end], linewidth=1.0, color="k") + axes.plot([axis_start, axis_end], [infinity, infinity], linewidth=1.0, color="k", alpha=alpha) + # Infinity label + yt = axes.get_yticks() + yt = yt[np.where(yt < axis_end)] # to avoid ploting ticklabel higher than infinity + yt = np.append(yt, infinity) + ytl = ["%.3f" % e for e in yt] # to avoid float precision error + ytl[-1] = r'$+\infty$' + axes.set_yticks(yt) + axes.set_yticklabels(ytl) if legend: dimensions = list(set(item[0] for item in persistence)) -- cgit v1.2.3