summaryrefslogtreecommitdiff
path: root/src/cython
diff options
context:
space:
mode:
authorvrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb>2018-08-09 09:16:14 +0000
committervrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb>2018-08-09 09:16:14 +0000
commit2871ff4d2bd23282ad2ee2925bea152262384641 (patch)
tree27fcfe639b63ed863db6a56c2003dcd96036b3a8 /src/cython
parent2a385b097c51fec5d72b8c1f9fd0eb1a19941a94 (diff)
Make soft dependency for matplotlib and numpy dependencies
git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ninja_cmake_warning_fix_vincent@3756 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 13a2e6e3eea8a36d0b9bdb4ab1c34f940a8932dc
Diffstat (limited to 'src/cython')
-rw-r--r--src/cython/CMakeLists.txt104
-rwxr-xr-xsrc/cython/cython/persistence_graphical_tools.py377
-rw-r--r--src/cython/setup.py.in6
3 files changed, 249 insertions, 238 deletions
diff --git a/src/cython/CMakeLists.txt b/src/cython/CMakeLists.txt
index 8b5d231a..1849a6ec 100644
--- a/src/cython/CMakeLists.txt
+++ b/src/cython/CMakeLists.txt
@@ -16,11 +16,13 @@ endfunction( add_gudhi_cython_lib )
# THE_TEST is the python test file name (without .py extension) containing tests functions
function( add_gudhi_py_test THE_TEST )
- # use ${PYTHON_EXECUTABLE} -B, otherwise a __pycache__ directory is created in sources by python
- # use py.test no cache provider, otherwise a .cache file is created in sources by py.test
- add_test(NAME ${THE_TEST}_py_test
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- COMMAND ${PYTHON_EXECUTABLE} -B -m pytest -p no:cacheprovider ${CMAKE_CURRENT_SOURCE_DIR}/test/${THE_TEST}.py)
+ if(PYTEST_FOUND)
+ # use ${PYTHON_EXECUTABLE} -B, otherwise a __pycache__ directory is created in sources by python
+ # use py.test no cache provider, otherwise a .cache file is created in sources by py.test
+ add_test(NAME ${THE_TEST}_py_test
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${PYTHON_EXECUTABLE} -B -m pytest -p no:cacheprovider ${CMAKE_CURRENT_SOURCE_DIR}/test/${THE_TEST}.py)
+ endif()
endfunction( add_gudhi_py_test )
# Set gudhi.__debug_info__
@@ -47,10 +49,10 @@ if(CYTHON_FOUND)
add_gudhi_debug_info("Pytest version ${PYTEST_VERSION}")
endif()
if(MATPLOTLIB_FOUND)
- add_gudhi_debug_info("Matplotlib version ${MATPLOTLIB_VERSION}")
+ add_gudhi_debug_info("Matplotlib version ${MATPLOTLIB_VERSION}")
endif()
if(NUMPY_FOUND)
- add_gudhi_debug_info("Numpy version ${NUMPY_VERSION}")
+ add_gudhi_debug_info("Numpy version ${NUMPY_VERSION}")
endif()
if(MATPLOTLIB_FOUND AND NUMPY_FOUND)
set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}persistence_graphical_tools;")
@@ -213,27 +215,29 @@ if(CYTHON_FOUND)
${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_rips_persistence_bottleneck_distance.py"
-f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -t 0.15 -d 3)
- # Tangential
- add_test(NAME tangential_complex_plain_homology_from_off_file_example_py_test
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
- ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/tangential_complex_plain_homology_from_off_file_example.py"
- --no-diagram -i 2 -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off)
-
- add_gudhi_py_test(test_tangential_complex)
-
- # Witness complex AND Subsampling
- add_test(NAME euclidean_strong_witness_complex_diagram_persistence_from_off_file_example_py_test
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
- ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py"
- --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 1.0 -n 20 -d 2)
-
- add_test(NAME euclidean_witness_complex_diagram_persistence_from_off_file_example_py_test
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
- ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py"
- --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 1.0 -n 20 -d 2)
+ if(MATPLOTLIB_FOUND AND NUMPY_FOUND)
+ # Tangential
+ add_test(NAME tangential_complex_plain_homology_from_off_file_example_py_test
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
+ ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/tangential_complex_plain_homology_from_off_file_example.py"
+ --no-diagram -i 2 -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off)
+
+ add_gudhi_py_test(test_tangential_complex)
+
+ # Witness complex AND Subsampling
+ add_test(NAME euclidean_strong_witness_complex_diagram_persistence_from_off_file_example_py_test
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
+ ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py"
+ --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 1.0 -n 20 -d 2)
+
+ add_test(NAME euclidean_witness_complex_diagram_persistence_from_off_file_example_py_test
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
+ ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py"
+ --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 1.0 -n 20 -d 2)
+ endif()
# Subsampling
add_gudhi_py_test(test_subsampling)
@@ -287,11 +291,13 @@ if(CYTHON_FOUND)
COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_complex_from_points_example.py")
- add_test(NAME alpha_complex_diagram_persistence_from_off_file_example_py_test
+ if(MATPLOTLIB_FOUND AND NUMPY_FOUND)
+ add_test(NAME alpha_complex_diagram_persistence_from_off_file_example_py_test
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_complex_diagram_persistence_from_off_file_example.py"
--no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 0.6)
+ endif()
add_gudhi_py_test(test_alpha_complex)
@@ -310,26 +316,30 @@ if(CYTHON_FOUND)
${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py"
--no-barcode -f ${CMAKE_SOURCE_DIR}/data/bitmap/CubicalTwoSphere.txt)
- add_test(NAME random_cubical_complex_persistence_example_py_test
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
- ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/random_cubical_complex_persistence_example.py"
- 10 10 10)
+ if(NUMPY_FOUND)
+ add_test(NAME random_cubical_complex_persistence_example_py_test
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
+ ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/random_cubical_complex_persistence_example.py"
+ 10 10 10)
+ endif()
add_gudhi_py_test(test_cubical_complex)
# Rips
- add_test(NAME rips_complex_diagram_persistence_from_distance_matrix_file_example_py_test
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
- ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py"
- --no-diagram -f ${CMAKE_SOURCE_DIR}/data/distance_matrix/lower_triangular_distance_matrix.csv -e 12.0 -d 3)
-
- add_test(NAME rips_complex_diagram_persistence_from_off_file_example_py_test
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
- ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/rips_complex_diagram_persistence_from_off_file_example.py
- --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -e 0.25 -d 3)
+ if(MATPLOTLIB_FOUND AND NUMPY_FOUND)
+ add_test(NAME rips_complex_diagram_persistence_from_distance_matrix_file_example_py_test
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
+ ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py"
+ --no-diagram -f ${CMAKE_SOURCE_DIR}/data/distance_matrix/lower_triangular_distance_matrix.csv -e 12.0 -d 3)
+
+ add_test(NAME rips_complex_diagram_persistence_from_off_file_example_py_test
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
+ ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/rips_complex_diagram_persistence_from_off_file_example.py
+ --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -e 0.25 -d 3)
+ endif()
add_test(NAME rips_complex_from_points_example_py_test
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
@@ -358,7 +368,7 @@ if(CYTHON_FOUND)
add_gudhi_py_test(test_reader_utils)
# Documentation generation is available through sphinx - requires all modules
- if(SPHINX_PATH AND NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1)
+ if(SPHINX_PATH AND MATPLOTLIB_FOUND AND NUMPY_FOUND AND NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1)
set (GUDHI_SPHINX_MESSAGE "Generating API documentation with Sphinx in ${CMAKE_CURRENT_BINARY_DIR}/sphinx/")
# User warning - Sphinx is a static pages generator, and configured to work fine with user_version
# Images and biblio warnings because not found on developper version
@@ -378,5 +388,5 @@ if(CYTHON_FOUND)
COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
${SPHINX_PATH} -b doctest ${CMAKE_CURRENT_SOURCE_DIR}/doc ${CMAKE_CURRENT_BINARY_DIR}/doctest)
- endif(SPHINX_PATH AND NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1)
+ endif()
endif(CYTHON_FOUND)
diff --git a/src/cython/cython/persistence_graphical_tools.py b/src/cython/cython/persistence_graphical_tools.py
index 216ab8d6..314bd6db 100755
--- a/src/cython/cython/persistence_graphical_tools.py
+++ b/src/cython/cython/persistence_graphical_tools.py
@@ -1,8 +1,3 @@
-import matplotlib.pyplot as plt
-import matplotlib.patches as mpatches
-import numpy as np
-import os
-
"""This file is part of the Gudhi Library. The Gudhi library
(Geometric Understanding in Higher Dimensions) is a generic C++
library for computational topology.
@@ -29,187 +24,197 @@ __author__ = "Vincent Rouvreau, Bertrand Michel"
__copyright__ = "Copyright (C) 2016 Inria"
__license__ = "GPL v3"
-def __min_birth_max_death(persistence, band=0.):
- """This function returns (min_birth, max_death) from the persistence.
-
- :param persistence: The persistence to plot.
- :type persistence: list of tuples(dimension, tuple(birth, death)).
- :param band: band
- :type band: float.
- :returns: (float, float) -- (min_birth, max_death).
- """
- # Look for minimum birth date and maximum death date for plot optimisation
- max_death = 0
- min_birth = persistence[0][1][0]
- for interval in reversed(persistence):
- if float(interval[1][1]) != float('inf'):
- if float(interval[1][1]) > max_death:
- max_death = float(interval[1][1])
- if float(interval[1][0]) > max_death:
- max_death = float(interval[1][0])
- if float(interval[1][0]) < min_birth:
- min_birth = float(interval[1][0])
- if band > 0.:
- max_death += band
- return (min_birth, max_death)
+try:
+ import matplotlib.pyplot as plt
+ import matplotlib.patches as mpatches
+ import numpy as np
+ import os
+
+ def __min_birth_max_death(persistence, band=0.):
+ """This function returns (min_birth, max_death) from the persistence.
+
+ :param persistence: The persistence to plot.
+ :type persistence: list of tuples(dimension, tuple(birth, death)).
+ :param band: band
+ :type band: float.
+ :returns: (float, float) -- (min_birth, max_death).
+ """
+ # Look for minimum birth date and maximum death date for plot optimisation
+ max_death = 0
+ min_birth = persistence[0][1][0]
+ for interval in reversed(persistence):
+ if float(interval[1][1]) != float('inf'):
+ if float(interval[1][1]) > max_death:
+ max_death = float(interval[1][1])
+ if float(interval[1][0]) > max_death:
+ max_death = float(interval[1][0])
+ if float(interval[1][0]) < min_birth:
+ min_birth = float(interval[1][0])
+ if band > 0.:
+ max_death += band
+ return (min_birth, max_death)
-"""
-Only 13 colors for the palette
-"""
-palette = ['#ff0000', '#00ff00', '#0000ff', '#00ffff', '#ff00ff', '#ffff00',
- '#000000', '#880000', '#008800', '#000088', '#888800', '#880088',
- '#008888']
-
-def plot_persistence_barcode(persistence=[], persistence_file='', alpha=0.6,
- max_barcodes=1000, inf_delta=0.1, legend=False):
- """This function plots the persistence bar code from persistence values list
- or from a :doc:`persistence file <fileformats>`.
-
- :param persistence: Persistence values list.
- :type persistence: list of tuples(dimension, tuple(birth, death)).
- :param persistence_file: A :doc:`persistence file <fileformats>` style name
- (reset persistence if both are set).
- :type persistence_file: string
- :param alpha: barcode transparency value (0.0 transparent through 1.0 opaque - default is 0.6).
- :type alpha: float.
- :param max_barcodes: number of maximal barcodes to be displayed.
- Set it to 0 to see all, Default value is 1000.
- (persistence will be sorted by life time if max_barcodes is set)
- :type max_barcodes: int.
- :param inf_delta: Infinity is placed at ((max_death - min_birth) x inf_delta).
- A reasonable value is between 0.05 and 0.5 - default is 0.1.
- :type inf_delta: float.
- :returns: A matplotlib object containing horizontal bar plot of persistence
- (launch `show()` method on it to display it).
"""
- if persistence_file is not '':
- if os.path.isfile(persistence_file):
- # Reset persistence
- persistence = []
- diag = read_persistence_intervals_grouped_by_dimension(persistence_file=persistence_file)
- for key in diag.keys():
- for persistence_interval in diag[key]:
- persistence.append((key, persistence_interval))
- else:
- print("file " + persistence_file + " not found.")
- return None
-
- if max_barcodes > 0 and max_barcodes < len(persistence):
- # Sort by life time, then takes only the max_plots elements
- persistence = sorted(persistence, key=lambda life_time: life_time[1][1]-life_time[1][0], reverse=True)[:max_barcodes]
-
- persistence = sorted(persistence, key=lambda birth: birth[1][0])
-
- (min_birth, max_death) = __min_birth_max_death(persistence)
- ind = 0
- delta = ((max_death - min_birth) * inf_delta)
- # Replace infinity values with max_death + delta for bar code to be more
- # readable
- infinity = max_death + delta
- axis_start = min_birth - delta
- # Draw horizontal bars in loop
- for interval in reversed(persistence):
- if float(interval[1][1]) != float('inf'):
- # Finite death case
- plt.barh(ind, (interval[1][1] - interval[1][0]), height=0.8,
- left = interval[1][0], alpha=alpha,
- color = palette[interval[0]],
- linewidth=0)
- else:
- # Infinite death case for diagram to be nicer
- plt.barh(ind, (infinity - interval[1][0]), height=0.8,
- left = interval[1][0], alpha=alpha,
- color = palette[interval[0]],
- linewidth=0)
- ind = ind + 1
-
- if legend:
- dimensions = list(set(item[0] for item in persistence))
- plt.legend(handles=[mpatches.Patch(color=palette[dim],
- label=str(dim)) for dim in dimensions],
- loc='lower right')
- plt.title('Persistence barcode')
- # Ends plot on infinity value and starts a little bit before min_birth
- plt.axis([axis_start, infinity, 0, ind])
- return plt
-
-def plot_persistence_diagram(persistence=[], persistence_file='', alpha=0.6,
- band=0., max_plots=1000, inf_delta=0.1, legend=False):
- """This function plots the persistence diagram from persistence values list
- or from a :doc:`persistence file <fileformats>`.
-
- :param persistence: Persistence values list.
- :type persistence: list of tuples(dimension, tuple(birth, death)).
- :param persistence_file: A :doc:`persistence file <fileformats>` style name
- (reset persistence if both are set).
- :type persistence_file: string
- :param alpha: plot transparency value (0.0 transparent through 1.0 opaque - default is 0.6).
- :type alpha: float.
- :param band: band (not displayed if :math:`\leq` 0. - default is 0.)
- :type band: float.
- :param max_plots: number of maximal plots to be displayed
- Set it to 0 to see all, Default value is 1000.
- (persistence will be sorted by life time if max_plots is set)
- :type max_plots: int.
- :param inf_delta: Infinity is placed at ((max_death - min_birth) x inf_delta).
- A reasonable value is between 0.05 and 0.5 - default is 0.1.
- :type inf_delta: float.
- :returns: A matplotlib object containing diagram plot of persistence
- (launch `show()` method on it to display it).
+ Only 13 colors for the palette
"""
- if persistence_file is not '':
- if os.path.isfile(persistence_file):
- # Reset persistence
- persistence = []
- diag = read_persistence_intervals_grouped_by_dimension(persistence_file=persistence_file)
- for key in diag.keys():
- for persistence_interval in diag[key]:
- persistence.append((key, persistence_interval))
- else:
- print("file " + persistence_file + " not found.")
- return None
-
- if max_plots > 0 and max_plots < len(persistence):
- # Sort by life time, then takes only the max_plots elements
- persistence = sorted(persistence, key=lambda life_time: life_time[1][1]-life_time[1][0], reverse=True)[:max_plots]
-
- (min_birth, max_death) = __min_birth_max_death(persistence, band)
- ind = 0
- delta = ((max_death - min_birth) * inf_delta)
- # Replace infinity values with max_death + delta for diagram to be more
- # readable
- infinity = max_death + delta
- axis_start = min_birth - delta
-
- # line display of equation : birth = death
- x = np.linspace(axis_start, infinity, 1000)
- # infinity line and text
- plt.plot(x, x, color='k', linewidth=1.0)
- plt.plot(x, [infinity] * len(x), linewidth=1.0, color='k', alpha=alpha)
- plt.text(axis_start, infinity, r'$\infty$', color='k', alpha=alpha)
- # bootstrap band
- if band > 0.:
- plt.fill_between(x, x, x+band, alpha=alpha, facecolor='red')
-
- # Draw points in loop
- for interval in reversed(persistence):
- if float(interval[1][1]) != float('inf'):
- # Finite death case
- plt.scatter(interval[1][0], interval[1][1], alpha=alpha,
- color = palette[interval[0]])
- else:
- # Infinite death case for diagram to be nicer
- plt.scatter(interval[1][0], infinity, alpha=alpha,
- color = palette[interval[0]])
- ind = ind + 1
-
- if legend:
- dimensions = list(set(item[0] for item in persistence))
- plt.legend(handles=[mpatches.Patch(color=palette[dim], label=str(dim)) for dim in dimensions])
-
- plt.title('Persistence diagram')
- plt.xlabel('Birth')
- plt.ylabel('Death')
- # Ends plot on infinity value and starts a little bit before min_birth
- plt.axis([axis_start, infinity, axis_start, infinity + delta])
- return plt
+ palette = ['#ff0000', '#00ff00', '#0000ff', '#00ffff', '#ff00ff', '#ffff00',
+ '#000000', '#880000', '#008800', '#000088', '#888800', '#880088',
+ '#008888']
+
+ def plot_persistence_barcode(persistence=[], persistence_file='', alpha=0.6,
+ max_barcodes=1000, inf_delta=0.1, legend=False):
+ """This function plots the persistence bar code from persistence values list
+ or from a :doc:`persistence file <fileformats>`.
+
+ :param persistence: Persistence values list.
+ :type persistence: list of tuples(dimension, tuple(birth, death)).
+ :param persistence_file: A :doc:`persistence file <fileformats>` style name
+ (reset persistence if both are set).
+ :type persistence_file: string
+ :param alpha: barcode transparency value (0.0 transparent through 1.0 opaque - default is 0.6).
+ :type alpha: float.
+ :param max_barcodes: number of maximal barcodes to be displayed.
+ Set it to 0 to see all, Default value is 1000.
+ (persistence will be sorted by life time if max_barcodes is set)
+ :type max_barcodes: int.
+ :param inf_delta: Infinity is placed at ((max_death - min_birth) x inf_delta).
+ A reasonable value is between 0.05 and 0.5 - default is 0.1.
+ :type inf_delta: float.
+ :returns: A matplotlib object containing horizontal bar plot of persistence
+ (launch `show()` method on it to display it).
+ """
+ if persistence_file is not '':
+ if os.path.isfile(persistence_file):
+ # Reset persistence
+ persistence = []
+ diag = read_persistence_intervals_grouped_by_dimension(persistence_file=persistence_file)
+ for key in diag.keys():
+ for persistence_interval in diag[key]:
+ persistence.append((key, persistence_interval))
+ else:
+ print("file " + persistence_file + " not found.")
+ return None
+
+ if max_barcodes > 0 and max_barcodes < len(persistence):
+ # Sort by life time, then takes only the max_plots elements
+ persistence = sorted(persistence, key=lambda life_time: life_time[1][1]-life_time[1][0], reverse=True)[:max_barcodes]
+
+ persistence = sorted(persistence, key=lambda birth: birth[1][0])
+
+ (min_birth, max_death) = __min_birth_max_death(persistence)
+ ind = 0
+ delta = ((max_death - min_birth) * inf_delta)
+ # Replace infinity values with max_death + delta for bar code to be more
+ # readable
+ infinity = max_death + delta
+ axis_start = min_birth - delta
+ # Draw horizontal bars in loop
+ for interval in reversed(persistence):
+ if float(interval[1][1]) != float('inf'):
+ # Finite death case
+ plt.barh(ind, (interval[1][1] - interval[1][0]), height=0.8,
+ left = interval[1][0], alpha=alpha,
+ color = palette[interval[0]],
+ linewidth=0)
+ else:
+ # Infinite death case for diagram to be nicer
+ plt.barh(ind, (infinity - interval[1][0]), height=0.8,
+ left = interval[1][0], alpha=alpha,
+ color = palette[interval[0]],
+ linewidth=0)
+ ind = ind + 1
+
+ if legend:
+ dimensions = list(set(item[0] for item in persistence))
+ plt.legend(handles=[mpatches.Patch(color=palette[dim],
+ label=str(dim)) for dim in dimensions],
+ loc='lower right')
+ plt.title('Persistence barcode')
+ # Ends plot on infinity value and starts a little bit before min_birth
+ plt.axis([axis_start, infinity, 0, ind])
+ return plt
+
+ def plot_persistence_diagram(persistence=[], persistence_file='', alpha=0.6,
+ band=0., max_plots=1000, inf_delta=0.1, legend=False):
+ """This function plots the persistence diagram from persistence values list
+ or from a :doc:`persistence file <fileformats>`.
+
+ :param persistence: Persistence values list.
+ :type persistence: list of tuples(dimension, tuple(birth, death)).
+ :param persistence_file: A :doc:`persistence file <fileformats>` style name
+ (reset persistence if both are set).
+ :type persistence_file: string
+ :param alpha: plot transparency value (0.0 transparent through 1.0 opaque - default is 0.6).
+ :type alpha: float.
+ :param band: band (not displayed if :math:`\leq` 0. - default is 0.)
+ :type band: float.
+ :param max_plots: number of maximal plots to be displayed
+ Set it to 0 to see all, Default value is 1000.
+ (persistence will be sorted by life time if max_plots is set)
+ :type max_plots: int.
+ :param inf_delta: Infinity is placed at ((max_death - min_birth) x inf_delta).
+ A reasonable value is between 0.05 and 0.5 - default is 0.1.
+ :type inf_delta: float.
+ :returns: A matplotlib object containing diagram plot of persistence
+ (launch `show()` method on it to display it).
+ """
+ if persistence_file is not '':
+ if os.path.isfile(persistence_file):
+ # Reset persistence
+ persistence = []
+ diag = read_persistence_intervals_grouped_by_dimension(persistence_file=persistence_file)
+ for key in diag.keys():
+ for persistence_interval in diag[key]:
+ persistence.append((key, persistence_interval))
+ else:
+ print("file " + persistence_file + " not found.")
+ return None
+
+ if max_plots > 0 and max_plots < len(persistence):
+ # Sort by life time, then takes only the max_plots elements
+ persistence = sorted(persistence, key=lambda life_time: life_time[1][1]-life_time[1][0], reverse=True)[:max_plots]
+
+ (min_birth, max_death) = __min_birth_max_death(persistence, band)
+ ind = 0
+ delta = ((max_death - min_birth) * inf_delta)
+ # Replace infinity values with max_death + delta for diagram to be more
+ # readable
+ infinity = max_death + delta
+ axis_start = min_birth - delta
+
+ # line display of equation : birth = death
+ x = np.linspace(axis_start, infinity, 1000)
+ # infinity line and text
+ plt.plot(x, x, color='k', linewidth=1.0)
+ plt.plot(x, [infinity] * len(x), linewidth=1.0, color='k', alpha=alpha)
+ plt.text(axis_start, infinity, r'$\infty$', color='k', alpha=alpha)
+ # bootstrap band
+ if band > 0.:
+ plt.fill_between(x, x, x+band, alpha=alpha, facecolor='red')
+
+ # Draw points in loop
+ for interval in reversed(persistence):
+ if float(interval[1][1]) != float('inf'):
+ # Finite death case
+ plt.scatter(interval[1][0], interval[1][1], alpha=alpha,
+ color = palette[interval[0]])
+ else:
+ # Infinite death case for diagram to be nicer
+ plt.scatter(interval[1][0], infinity, alpha=alpha,
+ color = palette[interval[0]])
+ ind = ind + 1
+
+ if legend:
+ dimensions = list(set(item[0] for item in persistence))
+ plt.legend(handles=[mpatches.Patch(color=palette[dim], label=str(dim)) for dim in dimensions])
+
+ plt.title('Persistence diagram')
+ plt.xlabel('Birth')
+ plt.ylabel('Death')
+ # Ends plot on infinity value and starts a little bit before min_birth
+ plt.axis([axis_start, infinity, axis_start, infinity + delta])
+ return plt
+
+except ImportError:
+ # Continue in case of import error, functions won't be available
+ pass
diff --git a/src/cython/setup.py.in b/src/cython/setup.py.in
index ee381a1b..4037aab6 100644
--- a/src/cython/setup.py.in
+++ b/src/cython/setup.py.in
@@ -46,9 +46,5 @@ setup(
version='@GUDHI_VERSION@',
url='http://gudhi.gforge.inria.fr/',
ext_modules = cythonize(gudhi),
- install_requires = [
- "matplotlib",
- "numpy",
- "cython",
- ],
+ install_requires = ["cython",],
)