Skip to content

[DOC] Add examples gallery #328

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
May 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import os
import re
from datetime import date
from distutils.version import LooseVersion

import sphinx

Expand Down Expand Up @@ -44,15 +43,10 @@ def find_var(varname: str, *py_file_paths):
"autoapi.extension",
"sphinx.ext.autodoc",
"sphinx.ext.autosummary",
# 'sphinx.ext.doctest',
"sphinx.ext.intersphinx",
# 'sphinx.ext.viewcode',
"numpydoc",
# 'rinoh.frontend.sphinx',
"sphinx_rtd_theme",
# 'sphinx.ext.napoleon',
# 'pytsdtwdoc',
# 'sphinx_gallery.gen_gallery',
"sphinx_gallery.gen_gallery",
"myst_nb",
"sphinxcontrib.bibtex",
]
Expand All @@ -67,7 +61,7 @@ def find_var(varname: str, *py_file_paths):
"dollarmath",
"colon_fence",
]

nb_execution_timeout = 600
autoapi_dirs = ["../src"]
autoapi_root = "reference/api"
autodoc_typehints = "description"
Expand All @@ -79,6 +73,12 @@ def find_var(varname: str, *py_file_paths):
"imported-members",
]

sphinx_gallery_conf = {
"examples_dirs": "../examples", # path to your example scripts
"gallery_dirs": "auto_examples", # path to where to save gallery generated output
"notebook_images": "https://leaspy.readthedocs.io/en/stable/_images/",
}

# this is needed for some reason...
# see https://github.com/numpy/numpydoc/issues/69
numpydoc_show_class_members = True
Expand Down
4 changes: 3 additions & 1 deletion docs/get_started.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# Get started

## Installation

See page [Installation](install.md).

## Leaspy in a nutshell
For a quick overview of how to use Leaspy, see page [Leaspy in a nutshell](nutshell.md).

For a quick overview of how to use Leaspy, see the [quickstart example](auto_examples/plot_quickstart).
3 changes: 2 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
:caption: Getting Started

install
nutshell
auto_examples/plot_quickstart
```

```{toctree}
Expand All @@ -18,6 +18,7 @@ nutshell
:caption: Documentation

user_guide
auto_examples/index.rst
glossary
changelog
license
Expand Down
141 changes: 0 additions & 141 deletions docs/nutshell.md

This file was deleted.

4 changes: 4 additions & 0 deletions examples/GALLERY_HEADER.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Example gallery for Leaspy
==========================

This is a gallery of examples of how to use Leaspy to conduct various kind of analysis.
113 changes: 113 additions & 0 deletions examples/plot_quickstart.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
"""
Quickstart with Leaspy
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The link "Leaspy in a nutshell" in get started does not work

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for spotting that ! Fixed in cf34613

======================
"""

# %%
# Comprehensive example
# ---------------------
# We first load synthetic data in a long format to get of a grasp of longitudinal data:

from leaspy.datasets import load_dataset

alzheimer_df = load_dataset("alzheimer-multivariate")
print(alzheimer_df.columns)
alzheimer_df = alzheimer_df[["MMSE", "RAVLT", "FAQ", "FDG PET"]]
print(alzheimer_df.head())

# %%
# The data correspond to repeated visits (`TIME` index) of different participants (`ID` index).
# Each visit corresponds to the measurement of 4 different outcomes : the MMSE, the RAVLT, the FAQ and the FDG PET.
# If plotted, the data would look like the following:
#
# .. image:: ../alzheimer-observations.png
# :width: 600
# :alt: Alzeimer observations

# %%
# Where each color corresponds to a variable, and the connected dots corresponds to the repeated visits of a single participant.
# Not very engaging, right ? To go a step further, let's first encapsulate the data into the main `Data` container:

from leaspy.io.data import Data, Dataset

data = Data.from_dataframe(alzheimer_df)
dataset = Dataset(data)

# %%
# Leaspy core functionality is to estimate the group-average trajectory of the different variables that are measured in a population.
# Clinical scores often have a ceiling and a floor effect, so let's initialize a multivariate logistic model:

from leaspy.models import LogisticMultivariateModel

model = LogisticMultivariateModel(name="test-model", source_dimension=2)

# %%
# As well as the algorithm needed to estimate the group-average trajectory:

from leaspy.algo import AlgorithmSettings, algorithm_factory

fit_settings = AlgorithmSettings(
"mcmc_saem", seed=42, n_iter=100, progress_bar=False, save_periodicity=None
)
algorithm = algorithm_factory(fit_settings)
model.initialize(dataset, fit_settings.model_initialization_method)
algorithm.run(model, dataset)

# %%
# If we were to plot the measured average progression of the variables, see started example notebook for details, it would look like the following:
#
# .. image:: ../alzheimer-model.png
# :width: 600
# :alt: Alzeimer model

# %%
# We can also derive the individual trajectory of each subject.
# To do this, we use a personalization algorithm called `scipy_minimize`:

personalize_settings = AlgorithmSettings("scipy_minimize", seed=0, progress_bar=False)
algorithm = algorithm_factory(personalize_settings)
individual_parameters = algorithm.run(model, dataset)
print(individual_parameters.to_dataframe())

# %%
# Plotting the input participant data against its personalization would give the following, see started example notebook for details.
#
# .. image:: ../alzheimer-subject_trajectories.png
# :width: 600
# :alt: Alzeimer subject trajectories

# %%
# Using my own data
# -----------------
#
# Data format
# ...........
#
# Leaspy uses its own data container. To use it properly, you need to provide a csv file or a pandas.DataFrame in the right format: longitudinal data in a long format.
# Let's have a look at the data used in the previous example:

print(alzheimer_df.head())

# %%
# You **MUST** have `ID` and `TIME`, either in index or in the columns. The other columns must be the observed variables (also named features or endpoints). In this fashion, you have one column per feature and one line per visit.

# %%
# Data scale & constraints
# ........................
#
# Leaspy uses linear and logistic models. The features MUST be increasing with time. For the logistic model, you need to rescale your data between 0 and 1.
#

# %%
# Missing data
# ............
# Leaspy automatically handles missing data as long as they are encoded as nan in your pandas.DataFrame, or as empty values in your csv file.

# %%
# Going further
# .............
# You can check the [user_guide](../user_guide.md) and the full API documentation.
#
# You can also dive into the [examples](./index.rst).
#
# The [Disease Progression Modelling](https://disease-progression-modelling.github.io/) website also hosts a [mathematical introduction](https://disease-progression-modelling.github.io/pages/models/disease_course_mapping.html) and [tutorials](https://disease-progression-modelling.github.io/pages/notebooks/disease_course_mapping/disease_course_mapping.html) for Leaspy.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you refer to external references because the doc is not ready but in the long run it should not link to these contents right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be honest I just adapted the line from the old "Leaspy in a nutshell" page without even taking a look at what this points at....
If we have the content as part of our docs, then yes, we should totally point to it instead.

Loading