diff --git a/docs/background/README.md b/docs/background/README.md index f67f4eda..3a21d06d 100644 --- a/docs/background/README.md +++ b/docs/background/README.md @@ -35,7 +35,7 @@ plot_00_conceptual_intro.md ```{eval-rst} -.. plot:: scripts/basis_table_figs.py plot_raised_cosine_linear +.. plot:: scripts/basis_figs.py plot_raised_cosine_linear :show-source-link: False :height: 100px ``` diff --git a/docs/background/basis/README.md b/docs/background/basis/README.md index 74e9dde6..72a8a598 100644 --- a/docs/background/basis/README.md +++ b/docs/background/basis/README.md @@ -17,7 +17,7 @@ - **Evaluation/Convolution** - **Preferred Mode** * - **B-Spline** - - .. plot:: scripts/basis_table_figs.py plot_bspline + - .. plot:: scripts/basis_figs.py plot_bspline :show-source-link: False :height: 80px - :ref:`Grid cells ` @@ -25,7 +25,7 @@ :class:`~nemos.basis.BSplineConv` - 🟢 Eval * - **Cyclic B-Spline** - - .. plot:: scripts/basis_table_figs.py plot_cyclic_bspline + - .. plot:: scripts/basis_figs.py plot_cyclic_bspline :show-source-link: False :height: 80px - :ref:`Place cells ` @@ -33,7 +33,7 @@ :class:`~nemos.basis.CyclicBSplineConv` - 🟢 Eval * - **M-Spline** - - .. plot:: scripts/basis_table_figs.py plot_mspline + - .. plot:: scripts/basis_figs.py plot_mspline :show-source-link: False :height: 80px - :ref:`Place cells ` @@ -41,7 +41,7 @@ :class:`~nemos.basis.MSplineConv` - 🟢 Eval * - **Linearly Spaced Raised Cosine** - - .. plot:: scripts/basis_table_figs.py plot_raised_cosine_linear + - .. plot:: scripts/basis_figs.py plot_raised_cosine_linear :show-source-link: False :height: 80px - @@ -49,7 +49,7 @@ :class:`~nemos.basis.RaisedCosineLinearConv` - 🟢 Eval * - **Log Spaced Raised Cosine** - - .. plot:: scripts/basis_table_figs.py plot_raised_cosine_log + - .. plot:: scripts/basis_figs.py plot_raised_cosine_log :show-source-link: False :height: 80px - :ref:`Head Direction ` @@ -57,7 +57,7 @@ :class:`~nemos.basis.RaisedCosineLogConv` - 🔵 Conv * - **Orthogonalized Exponential Decays** - - .. plot:: scripts/basis_table_figs.py plot_orth_exp_basis + - .. plot:: scripts/basis_figs.py plot_orth_exp_basis :show-source-link: False :height: 80px - @@ -101,9 +101,12 @@ NeMoS provides a variety of basis functions (see the [table](table_basis) above) :::{grid-item-card} -
-One-Dimensional Basis. -
+```{eval-rst} + +.. plot:: scripts/basis_figs.py plot_1d_basis_thumbnail + :show-source-link: False + :height: 100px +``` ```{toctree} :maxdepth: 2 @@ -114,9 +117,12 @@ plot_01_1D_basis_function.md :::{grid-item-card} -
-N-Dimensional Basis. -
+```{eval-rst} + +.. plot:: scripts/basis_figs.py plot_nd_basis_thumbnail + :show-source-link: False + :height: 100px +``` ```{toctree} :maxdepth: 2 diff --git a/docs/background/basis/plot_01_1D_basis_function.md b/docs/background/basis/plot_01_1D_basis_function.md index 31131bf2..d4ac0070 100644 --- a/docs/background/basis/plot_01_1D_basis_function.md +++ b/docs/background/basis/plot_01_1D_basis_function.md @@ -81,30 +81,6 @@ plt.plot(x, y, lw=2) plt.title("B-Spline Basis") ``` -```{code-cell} ipython3 -:tags: [hide-input] - -# save image for thumbnail -from pathlib import Path -import os - -root = os.environ.get("READTHEDOCS_OUTPUT") -if root: - path = Path(root) / "html/_static/thumbnails/background" -# if local store in ../_build/html/... -else: - path = Path("../../_build/html/_static/thumbnails/background") - -# make sure the folder exists if run from build -if root or Path("../../_build/html/_static").exists(): - path.mkdir(parents=True, exist_ok=True) - -if path.exists(): - fig.savefig(path / "plot_01_1D_basis_function.svg") - - -print(path.resolve(), path.exists()) -``` ## Computing Features All bases in the `nemos.basis` module perform a transformation of one or more time series into a set of features. This operation is always carried out by the method [`compute_features`](nemos.basis._basis.Basis.compute_features). diff --git a/docs/background/basis/plot_02_ND_basis_function.md b/docs/background/basis/plot_02_ND_basis_function.md index 828e0ea8..9efeff40 100644 --- a/docs/background/basis/plot_02_ND_basis_function.md +++ b/docs/background/basis/plot_02_ND_basis_function.md @@ -292,28 +292,6 @@ axs[2, 1].set_xlabel('y-coord') plt.tight_layout() ``` -```{code-cell} ipython3 -:tags: [hide-input] - -# save image for thumbnail -from pathlib import Path -import os - -root = os.environ.get("READTHEDOCS_OUTPUT") -if root: - path = Path(root) / "html/_static/thumbnails/background" -# if local store in ../_build/html/... -else: - path = Path("../../_build/html/_static/thumbnails/background") - -# make sure the folder exists if run from build -if root or Path("../_build/html/_static").exists(): - path.mkdir(parents=True, exist_ok=True) - -if path.exists(): - fig.savefig(path / "plot_02_ND_basis_function.svg") -``` - :::{note} Basis objects of different types can be combined through multiplication or addition. This feature is particularly useful when one of the axes represents a periodic variable and another is non-periodic. diff --git a/docs/background/plot_03_1D_convolution.md b/docs/background/plot_03_1D_convolution.md index 1967148d..a237a0f7 100644 --- a/docs/background/plot_03_1D_convolution.md +++ b/docs/background/plot_03_1D_convolution.md @@ -179,7 +179,7 @@ else: path = Path("../_build/html/_static/thumbnails/background") # make sure the folder exists if run from build -if root or Path("../_build/html/_static").exists(): +if root or Path("../assets/stylesheets").exists(): path.mkdir(parents=True, exist_ok=True) if path.exists(): diff --git a/docs/how_to_guide/plot_02_glm_demo.md b/docs/how_to_guide/plot_02_glm_demo.md index 83591da4..511a9d8c 100644 --- a/docs/how_to_guide/plot_02_glm_demo.md +++ b/docs/how_to_guide/plot_02_glm_demo.md @@ -450,7 +450,7 @@ else: path = Path("../_build/html/_static/thumbnails/how_to_guide") # make sure the folder exists if run from build -if root or Path("../_build/html/_static").exists(): +if root or Path("../assets/stylesheets").exists(): path.mkdir(parents=True, exist_ok=True) if path.exists(): diff --git a/docs/how_to_guide/plot_03_population_glm.md b/docs/how_to_guide/plot_03_population_glm.md index 7c27acd5..a129a65e 100644 --- a/docs/how_to_guide/plot_03_population_glm.md +++ b/docs/how_to_guide/plot_03_population_glm.md @@ -231,7 +231,7 @@ else: path = Path("../_build/html/_static/thumbnails/how_to_guide") # make sure the folder exists if run from build -if root or Path("../_build/html/_static").exists(): +if root or Path("../assets/stylesheets").exists(): path.mkdir(parents=True, exist_ok=True) if path.exists(): diff --git a/docs/how_to_guide/plot_04_batch_glm.md b/docs/how_to_guide/plot_04_batch_glm.md index 217de9ba..36bd31b8 100644 --- a/docs/how_to_guide/plot_04_batch_glm.md +++ b/docs/how_to_guide/plot_04_batch_glm.md @@ -208,7 +208,7 @@ else: path = Path("../_build/html/_static/thumbnails/how_to_guide") # make sure the folder exists if run from build -if root or Path("../_build/html/_static").exists(): +if root or Path("../assets/stylesheets").exists(): path.mkdir(parents=True, exist_ok=True) if path.exists(): diff --git a/docs/how_to_guide/plot_05_sklearn_pipeline_cv_demo.md b/docs/how_to_guide/plot_05_sklearn_pipeline_cv_demo.md index 166a5cbb..9f5a9652 100644 --- a/docs/how_to_guide/plot_05_sklearn_pipeline_cv_demo.md +++ b/docs/how_to_guide/plot_05_sklearn_pipeline_cv_demo.md @@ -435,7 +435,7 @@ else: path = Path("../_build/html/_static/thumbnails/how_to_guide") # make sure the folder exists if run from build -if root or Path("../_build/html/_static").exists(): +if root or Path("../assets/stylesheets").exists(): path.mkdir(parents=True, exist_ok=True) if path.exists(): diff --git a/docs/how_to_guide/plot_06_glm_pytree.md b/docs/how_to_guide/plot_06_glm_pytree.md index e5949f58..4c82be40 100644 --- a/docs/how_to_guide/plot_06_glm_pytree.md +++ b/docs/how_to_guide/plot_06_glm_pytree.md @@ -261,7 +261,7 @@ else: path = Path("../_build/html/_static/thumbnails/how_to_guide") # make sure the folder exists if run from build -if root or Path("../_build/html/_static").exists(): +if root or Path("../assets/stylesheets").exists(): path.mkdir(parents=True, exist_ok=True) if path.exists(): diff --git a/docs/scripts/basis_figs.py b/docs/scripts/basis_figs.py new file mode 100644 index 00000000..5113a577 --- /dev/null +++ b/docs/scripts/basis_figs.py @@ -0,0 +1,108 @@ +import matplotlib.pyplot as plt +import numpy as np + +import nemos as nmo +from nemos._inspect_utils.inspect_utils import trim_kwargs + +plt.rcParams.update( + { + "figure.dpi": 300, + } +) + +KWARGS = dict( + n_basis_funcs=10, + decay_rates=np.arange(1, 10 + 1), + enforce_decay_to_zero=True, + order=4, + width=2, +) + + +def plot_basis(cls): + cls_params = cls._get_param_names() + new_kwargs = trim_kwargs(cls, KWARGS.copy(), {cls.__name__: cls_params}) + bas = cls(**new_kwargs) + fig, ax = plt.subplots(1, 1, figsize=(5, 2.5)) + ax.plot(*bas.evaluate_on_grid(300), lw=4) + for side in ["left", "right", "top", "bottom"]: + ax.spines[side].set_visible(False) + ax.set_xticks([]) + ax.set_yticks([]) + plt.subplots_adjust(left=0.02, right=0.98, top=0.98, bottom=0.02) + + +def plot_raised_cosine_linear(): + plot_basis(nmo.basis.RaisedCosineLinearEval) + + +def plot_raised_cosine_log(): + plot_basis(nmo.basis.RaisedCosineLogEval) + + +def plot_mspline(): + plot_basis(nmo.basis.MSplineEval) + + +def plot_bspline(): + plot_basis(nmo.basis.BSplineEval) + + +def plot_cyclic_bspline(): + plot_basis(nmo.basis.CyclicBSplineEval) + + +def plot_orth_exp_basis(): + plot_basis(nmo.basis.OrthExponentialEval) + + +def plot_nd_basis_thumbnail(): + a_basis = nmo.basis.MSplineEval(n_basis_funcs=15, order=3) + b_basis = nmo.basis.RaisedCosineLogEval(n_basis_funcs=14) + prod_basis = a_basis * b_basis + + x_coord = np.linspace(0, 1, 1000) + y_coord = np.linspace(0, 1, 1000) + + X, Y, Z = prod_basis.evaluate_on_grid(200, 200) + + # basis element pairs + element_pairs = [[0, 0], [5, 1], [10, 5]] + + # plot the 1D basis element and their product + fig, axs = plt.subplots(3,3,figsize=(8, 6)) + cc = 0 + for i, j in element_pairs: + # plot the element form a_basis + axs[cc, 0].plot(x_coord, a_basis.compute_features(x_coord), "grey", alpha=.3) + axs[cc, 0].plot(x_coord, a_basis.compute_features(x_coord)[:, i], "b") + axs[cc, 0].set_title(f"$a_{{{i}}}(x)$",color='b') + + # plot the element form b_basis + axs[cc, 1].plot(y_coord, b_basis.compute_features(y_coord), "grey", alpha=.3) + axs[cc, 1].plot(y_coord, b_basis.compute_features(y_coord)[:, j], "b") + axs[cc, 1].set_title(f"$b_{{{j}}}(y)$",color='b') + + # select & plot the corresponding product basis element + k = i * b_basis.n_basis_funcs + j + axs[cc, 2].contourf(X, Y, Z[:, :, k], cmap='Blues') + axs[cc, 2].set_title(fr"$A_{{{k}}}(x,y) = a_{{{i}}}(x) \cdot b_{{{j}}}(y)$", color='b') + axs[cc, 2].set_xlabel('x-coord') + axs[cc, 2].set_ylabel('y-coord') + axs[cc, 2].set_aspect("equal") + + cc += 1 + axs[2, 0].set_xlabel('x-coord') + axs[2, 1].set_xlabel('y-coord') + + plt.tight_layout() + +def plot_1d_basis_thumbnail(): + order = 4 + n_basis = 10 + bspline = nmo.basis.BSplineEval(n_basis_funcs=n_basis, order=order) + x, y = bspline.evaluate_on_grid(100) + + plt.figure(figsize=(5, 3)) + plt.plot(x, y, lw=2) + plt.title("B-Spline Basis") \ No newline at end of file diff --git a/docs/scripts/basis_table_figs.py b/docs/scripts/basis_table_figs.py deleted file mode 100644 index f60bed8c..00000000 --- a/docs/scripts/basis_table_figs.py +++ /dev/null @@ -1,56 +0,0 @@ -import matplotlib.pyplot as plt -import numpy as np - -import nemos as nmo -from nemos._inspect_utils import trim_kwargs - -plt.rcParams.update( - { - "figure.dpi": 300, - } -) - -KWARGS = dict( - n_basis_funcs=10, - decay_rates=np.arange(1, 10 + 1), - enforce_decay_to_zero=True, - order=4, - width=2, -) - - -def plot_basis(cls): - cls_params = cls._get_param_names() - new_kwargs = trim_kwargs(cls, KWARGS.copy(), {cls.__name__: cls_params}) - bas = cls(**new_kwargs) - fig, ax = plt.subplots(1, 1, figsize=(5, 2.5)) - ax.plot(*bas.evaluate_on_grid(300), lw=4) - for side in ["left", "right", "top", "bottom"]: - ax.spines[side].set_visible(False) - ax.set_xticks([]) - ax.set_yticks([]) - plt.subplots_adjust(left=0.02, right=0.98, top=0.98, bottom=0.02) - - -def plot_raised_cosine_linear(): - plot_basis(nmo.basis.RaisedCosineLinearEval) - - -def plot_raised_cosine_log(): - plot_basis(nmo.basis.RaisedCosineLogEval) - - -def plot_mspline(): - plot_basis(nmo.basis.MSplineEval) - - -def plot_bspline(): - plot_basis(nmo.basis.BSplineEval) - - -def plot_cyclic_bspline(): - plot_basis(nmo.basis.CyclicBSplineEval) - - -def plot_orth_exp_basis(): - plot_basis(nmo.basis.OrthExponentialEval) diff --git a/docs/tutorials/plot_01_current_injection.md b/docs/tutorials/plot_01_current_injection.md index bffd5a35..361f513b 100644 --- a/docs/tutorials/plot_01_current_injection.md +++ b/docs/tutorials/plot_01_current_injection.md @@ -635,7 +635,7 @@ else: path = Path("../_build/html/_static/thumbnails/tutorials") # make sure the folder exists if run from build -if root or Path("../_build/html/_static").exists(): +if root or Path("../assets/stylesheets").exists(): path.mkdir(parents=True, exist_ok=True) if path.exists(): diff --git a/docs/tutorials/plot_02_head_direction.md b/docs/tutorials/plot_02_head_direction.md index 6a44fdd7..c038c0fa 100644 --- a/docs/tutorials/plot_02_head_direction.md +++ b/docs/tutorials/plot_02_head_direction.md @@ -717,7 +717,7 @@ else: path = Path("../_build/html/_static/thumbnails/tutorials") # make sure the folder exists if run from build -if root or Path("../_build/html/_static").exists(): +if root or Path("../assets/stylesheets").exists(): path.mkdir(parents=True, exist_ok=True) if path.exists(): diff --git a/docs/tutorials/plot_03_grid_cells.md b/docs/tutorials/plot_03_grid_cells.md index 6d244f28..75659a5e 100644 --- a/docs/tutorials/plot_03_grid_cells.md +++ b/docs/tutorials/plot_03_grid_cells.md @@ -348,7 +348,7 @@ else: path = Path("../_build/html/_static/thumbnails/tutorials") # make sure the folder exists if run from build -if root or Path("../_build/html/_static").exists(): +if root or Path("../assets/stylesheets").exists(): path.mkdir(parents=True, exist_ok=True) if path.exists(): diff --git a/docs/tutorials/plot_04_v1_cells.md b/docs/tutorials/plot_04_v1_cells.md index c9faaa82..3ee0bcff 100644 --- a/docs/tutorials/plot_04_v1_cells.md +++ b/docs/tutorials/plot_04_v1_cells.md @@ -247,7 +247,7 @@ else: path = Path("../_build/html/_static/thumbnails/tutorials") # make sure the folder exists if run from build -if root or Path("../_build/html/_static").exists(): +if root or Path("../assets/stylesheets").exists(): path.mkdir(parents=True, exist_ok=True) if path.exists(): diff --git a/docs/tutorials/plot_05_place_cells.md b/docs/tutorials/plot_05_place_cells.md index 4657c0f5..9726f5cb 100644 --- a/docs/tutorials/plot_05_place_cells.md +++ b/docs/tutorials/plot_05_place_cells.md @@ -159,7 +159,7 @@ else: path = Path("../_build/html/_static/thumbnails/tutorials") # make sure the folder exists if run from build -if root or Path("../_build/html/_static").exists(): +if root or Path("../assets/stylesheets").exists(): path.mkdir(parents=True, exist_ok=True) if path.exists(): diff --git a/docs/tutorials/plot_06_calcium_imaging.md b/docs/tutorials/plot_06_calcium_imaging.md index c95987a9..426f9b6a 100644 --- a/docs/tutorials/plot_06_calcium_imaging.md +++ b/docs/tutorials/plot_06_calcium_imaging.md @@ -371,7 +371,7 @@ else: path = Path("../_build/html/_static/thumbnails/tutorials") # make sure the folder exists if run from build -if root or Path("../_build/html/_static").exists(): +if root or Path("../assets/stylesheets").exists(): path.mkdir(parents=True, exist_ok=True) if path.exists(): diff --git a/src/nemos/_inspect_utils/__init__.py b/src/nemos/_inspect_utils/__init__.py index 21743bd6..0fec61ec 100644 --- a/src/nemos/_inspect_utils/__init__.py +++ b/src/nemos/_inspect_utils/__init__.py @@ -9,7 +9,7 @@ identify abstract classes, and verify method compliance in subclasses. """ -from .inpsect_utils import ( +from .inspect_utils import ( check_all_abstract_methods_compliance, get_abstract_classes, get_non_abstract_classes,