Skip to content

Commit 6574198

Browse files
authored
Merge branch 'main' into add-cover-examples
2 parents e08e969 + 1552297 commit 6574198

File tree

9 files changed

+80
-12
lines changed

9 files changed

+80
-12
lines changed

.github/workflows/test-bench.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,8 @@ jobs:
1313
runs-on: ubuntu-latest
1414
strategy:
1515
matrix:
16-
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
16+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
1717
include:
18-
- python-version: 3.8
19-
allow-failure: false
2018
- python-version: 3.9
2119
allow-failure: false
2220
- python-version: 3.10

.github/workflows/test-unit.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,11 @@ on:
1010

1111
jobs:
1212
test-unit-matrix-job:
13-
runs-on: ubuntu-22.04
13+
runs-on: ubuntu-latest
1414
strategy:
1515
matrix:
16-
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
16+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
1717
include:
18-
- python-version: 3.8
19-
allow-failure: false
2018
- python-version: 3.9
2119
allow-failure: false
2220
- python-version: 3.10

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
![Logo](https://github.com/lucasimi/tda-mapper-python/raw/main/docs/source/logos/tda-mapper-logo-horizontal.png)
22

3+
[![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active)
4+
35
[![PyPI version](https://img.shields.io/pypi/v/tda-mapper?logo=python&logoColor=silver)](https://pypi.python.org/pypi/tda-mapper)
46
[![downloads](https://img.shields.io/pypi/dm/tda-mapper?logo=python&logoColor=silver)](https://pypi.python.org/pypi/tda-mapper)
57
[![codecov](https://img.shields.io/codecov/c/github/lucasimi/tda-mapper-python?logo=codecov&logoColor=silver)](https://codecov.io/github/lucasimi/tda-mapper-python)

docs/source/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def convert_py_to_ipynb():
4646

4747
extensions = [
4848
"sphinx.ext.autodoc",
49+
"sphinx.ext.doctest",
4950
"sphinx.ext.viewcode",
5051
"sphinx_rtd_theme",
5152
"nbsphinx",

docs/source/index.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
.. |Repo Status| image:: https://www.repostatus.org/badges/latest/active.svg
2+
:alt: Project Status: Active – The project has reached a stable, usable state and is being actively developed.
3+
:target: https://www.repostatus.org/#active
14
.. |Source Code| image:: https://img.shields.io/badge/lucasimi-tda--mapper--python-blue?logo=github&logoColor=silver
25
:target: https://github.com/lucasimi/tda-mapper-python
36
.. |PyPI version| image:: https://img.shields.io/pypi/v/tda-mapper?logo=python&logoColor=silver
@@ -23,9 +26,10 @@
2326
https://github.com/lucasimi/tda-mapper-python/raw/main/docs/source/logos/tda-mapper-logo-horizontal.png
2427
:alt: Logo
2528

29+
|Repo Status| |Source Code|
30+
2631
|PyPI version| |downloads| |codecov| |test| |publish| |docs| |DOI|
2732

28-
|Source Code|
2933

3034
tda-mapper
3135
==========

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ classifiers = [
2020
"License :: OSI Approved :: Apache Software License",
2121
"Programming Language :: Python",
2222
"Programming Language :: Python :: 3",
23-
"Programming Language :: Python :: 3.8",
2423
"Programming Language :: Python :: 3.9",
2524
"Programming Language :: Python :: 3.10",
2625
"Programming Language :: Python :: 3.11",
2726
"Programming Language :: Python :: 3.12",
2827
"Programming Language :: Python :: 3.13",
2928
"Operating System :: OS Independent",
29+
"Development Status :: 5 - Production/Stable",
3030
]
3131
keywords = ["tda", "mapper", "topology", "topological data analysis"]
3232
dependencies = [
@@ -39,7 +39,7 @@ dependencies = [
3939
"plotly>=6.0.1,<7.0.0",
4040
"joblib>=1.4.2,<2.0.0",
4141
]
42-
requires-python = ">=3.8"
42+
requires-python = ">=3.9"
4343

4444
[project.optional-dependencies]
4545
dev = [

src/tdamapper/__init__.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
"""
2+
This library provides a Python implementation of the TDA Mapper algorithm,
3+
which is used for topological data analysis (TDA). The TDA Mapper algorithm
4+
is a method for extracting topological features from high-dimensional data
5+
by constructing a simplicial complex that captures the shape of the data.
6+
7+
The `tdamapper` package includes the following main modules:
8+
- `core`: Contains the core implementation of the Mapper algorithm.
9+
- `cover`: Provides classes for creating _open covers_, which are collections of overlapping sets
10+
that cover the data space.
11+
- `learn`: Includes classes compatible with scikit-learn's estimator API based on Mapper. These
12+
classes can be used in scikit-learn pipelines.
13+
- `utils`: Provides utility functions for creating spatial indexes.
14+
- `plot`: Contains functions for visualizing the Mapper graph.
15+
16+
To use the TDA Mapper algorithm, you can follow these steps:
17+
18+
Examples
19+
--------
20+
>>> from sklearn.datasets import make_circles
21+
>>>
22+
>>> import numpy as np
23+
>>> from sklearn.decomposition import PCA
24+
>>> from sklearn.cluster import DBSCAN
25+
>>>
26+
>>> from tdamapper.learn import MapperAlgorithm
27+
>>> from tdamapper.cover import CubicalCover
28+
>>> from tdamapper.plot import MapperPlot
29+
>>>
30+
>>> X, labels = make_circles(n_samples=5000, noise=0.05, factor=0.3, random_state=42)
31+
>>> y = PCA(2, random_state=42).fit_transform(X)
32+
>>>
33+
>>> cover = CubicalCover(n_intervals=10, overlap_frac=0.3)
34+
>>> clust = DBSCAN()
35+
>>> graph = MapperAlgorithm(cover, clust).fit_transform(X, y)
36+
>>>
37+
>>> fig = MapperPlot(graph, dim=2, seed=42, iterations=60).plot_plotly(colors=labels)
38+
>>> fig.show(config={"scrollZoom": True})
39+
"""

src/tdamapper/app.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,11 @@ def __init__(self, storage):
248248
themedark="#132f48",
249249
)
250250

251-
with ui.left_drawer(elevated=True).classes(
251+
self.left_drawer = ui.left_drawer(elevated=True).classes(
252252
"w-96 h-full overflow-y-auto gap-12"
253-
):
253+
)
254+
255+
with self.left_drawer:
254256
with ui.link(target=GIT_REPO_URL, new_tab=True).classes("w-full"):
255257
ui.image(LOGO_URL)
256258

@@ -541,6 +543,17 @@ def _init_draw_area(self):
541543
self.plot_container = ui.element("div").classes("w-full h-full")
542544
self.draw_area = None
543545

546+
def _toggle_drawer():
547+
self.left_drawer.toggle()
548+
if self.draw_area is not None:
549+
self.draw_area.update()
550+
551+
with ui.page_sticky(x_offset=18, y_offset=18, position="top-left"):
552+
ui.button(
553+
icon="menu",
554+
on_click=_toggle_drawer,
555+
).props("fab color=themedark")
556+
544557
def get_mapper_config(self):
545558
return MapperConfig(
546559
lens_type=str(self.lens_type.value) if self.lens_type.value else LENS_PCA,

tests/test_unit_app.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ async def test_run_app_success(user: User) -> None:
3434
await user.should_see("Clustering")
3535
await user.should_see("Run Mapper")
3636
await user.should_see("Redraw")
37+
38+
# Click on the toggle menu button to open the menu
39+
await user.should_see("menu")
40+
user.find("menu").click()
41+
await user.should_see("menu")
42+
user.find("menu").click()
43+
3744
user.find("Load Data").click()
3845
await user.should_see("Load data completed")
3946
await user.should_not_see("Load data failed")
@@ -49,6 +56,12 @@ async def test_run_app_success(user: User) -> None:
4956
await user.should_not_see("Draw Mapper failed")
5057
await user.should_see("Draw Mapper completed", retries=RETRIES)
5158

59+
# Click on the toggle menu button to open the menu
60+
await user.should_see("menu")
61+
user.find("menu").click()
62+
await user.should_see("menu")
63+
user.find("menu").click()
64+
5265

5366
def test_run_mapper() -> None:
5467
config = app.MapperConfig()

0 commit comments

Comments
 (0)