From fac14a9a11cd451e70981c2eca8435a6f6d8058f Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Thu, 14 Mar 2024 23:44:45 +0530 Subject: [PATCH 01/11] DOC: ignore unneeded directories and databases --- .gitignore | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitignore b/.gitignore index 1bd984aa3..870125286 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ __pycache__ *.egg-info dist build +_build .installed.cfg # Installer logs @@ -19,6 +20,11 @@ pip-log.txt .coverage .tox +# Sphinx documentation +doc/_build/ +doc/build/ +.jupyterlite.doit.db + # Editors .idea .project From 534833eb82a6fa639772448f2c07983947a3ea69 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Thu, 14 Mar 2024 23:45:25 +0530 Subject: [PATCH 02/11] DOC: add `jupyterlite-sphinx` to RTD requirements --- util/readthedocs/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/util/readthedocs/requirements.txt b/util/readthedocs/requirements.txt index 9ac8577c2..8f2c7bb49 100644 --- a/util/readthedocs/requirements.txt +++ b/util/readthedocs/requirements.txt @@ -1,5 +1,6 @@ cython docutils<0.18 +jupyterlite-sphinx pydata-sphinx-theme pytest matplotlib From ee7df9b0a64fbc582e925f93c589985e43ec3a65 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Thu, 14 Mar 2024 23:47:38 +0530 Subject: [PATCH 03/11] DOC: start to configure JupyterLite --- doc/source/conf.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/source/conf.py b/doc/source/conf.py index 647d34a34..dfb94f24d 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -34,6 +34,7 @@ # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ + 'jupyterlite_sphinx', 'matplotlib.sphinxext.plot_directive', 'numpydoc', 'sphinx.ext.autodoc', @@ -287,3 +288,8 @@ 'numpy': ('https://numpy.org/devdocs', None), 'scipy': ('https://docs.scipy.org/doc/scipy/reference', None), } + +# -- Options for JupyterLite ------------------------------------------------- + +global_enable_try_examples = True +try_examples_global_button_text = "Try it in your browser!" From 803ca135bba4c991586dd27c275f3f7c378ca89a Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Fri, 15 Mar 2024 01:25:34 +0530 Subject: [PATCH 04/11] DOC: ship a Pyodide kernel on RTD --- util/readthedocs/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/util/readthedocs/requirements.txt b/util/readthedocs/requirements.txt index 8f2c7bb49..9d7d537f1 100644 --- a/util/readthedocs/requirements.txt +++ b/util/readthedocs/requirements.txt @@ -1,6 +1,7 @@ cython docutils<0.18 jupyterlite-sphinx +jupyterlite-pyodide-kernel pydata-sphinx-theme pytest matplotlib From dcb3088f9a37ff4ff2cb7ad5d219cb97e4053308 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Fri, 15 Mar 2024 18:51:20 +0530 Subject: [PATCH 05/11] DOC: Reconfigure admonition for Pyodide kernels --- doc/source/conf.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/source/conf.py b/doc/source/conf.py index dfb94f24d..16d8b6d85 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -293,3 +293,12 @@ global_enable_try_examples = True try_examples_global_button_text = "Try it in your browser!" +try_examples_global_warning_text = ( +"""These interactive examples with JupyterLite are experimental and +may not always work as expected. The execution of cells containing import +statements can result in high bandwidth usage and may take a long time to +load. They may not be in sync with the latest PyWavelets release. + +Shall you encounter any issues, please feel free to report them on the +[PyWavelets issue tracker](https://github.com/PyWavelets/pywt/issues).""" +) From 9aaf45b229be65011920c89cb625200342bad81c Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Fri, 22 Mar 2024 12:15:27 +0530 Subject: [PATCH 06/11] DOC: Add custom CSS to style "Try" button --- doc/source/_static/pywavelets.css | 27 +++++++++++++++++++++++++++ doc/source/conf.py | 6 ++++++ 2 files changed, 33 insertions(+) create mode 100644 doc/source/_static/pywavelets.css diff --git a/doc/source/_static/pywavelets.css b/doc/source/_static/pywavelets.css new file mode 100644 index 000000000..56f12e4df --- /dev/null +++ b/doc/source/_static/pywavelets.css @@ -0,0 +1,27 @@ +/* Custom CSS rules for the interactive documentation button */ + +.try_examples_button { + color: white; + background-color: #0054a6; + border: none; + padding: 5px 10px; + border-radius: 10px; + margin-bottom: 5px; + box-shadow: 0 2px 5px rgba(108,108,108,0.2); + font-weight: bold; + font-size: small; +} + +.try_examples_button:hover { +background-color: #0066cc; +transform: scale(1.02); +box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); +cursor: pointer; +} + +.try_examples_button_container { + display: flex; + justify-content: flex-start; + gap: 10px; + margin-bottom: 20px; +} diff --git a/doc/source/conf.py b/doc/source/conf.py index 16d8b6d85..70ba4d222 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -194,6 +194,12 @@ # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] +# CSS files to include in the build. The file path should be relative to the +# _static directory. +html_css_files = [ + "pywavelets.css", +] + # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. html_last_updated_fmt = '%b %d, %Y' From f15c82213f1d1cedaf40b71a261d6532a66d288c Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Fri, 22 Mar 2024 13:04:39 +0530 Subject: [PATCH 07/11] DOC: Add a global minimum height for notebooks --- doc/source/try_examples.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 doc/source/try_examples.json diff --git a/doc/source/try_examples.json b/doc/source/try_examples.json new file mode 100644 index 000000000..d6eaca0c0 --- /dev/null +++ b/doc/source/try_examples.json @@ -0,0 +1,3 @@ +{ + "global_min_height": "600px" +} From 6d1145e4a7c1366c666f4197859c538b591d33d4 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Fri, 22 Mar 2024 16:53:38 +0530 Subject: [PATCH 08/11] DOC: Move example for `pywt.data.demo_signal()` This commit moves the example for the function `pywt.data.demo_signal()` to the doctests for the function instead of having it inside reST. This shall render the example interactive through the use of JupyterLite and the TryExamples Sphinx directive. --- doc/source/ref/other-functions.rst | 9 --------- pywt/data/_wavelab_signals.py | 10 ++++++++++ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/doc/source/ref/other-functions.rst b/doc/source/ref/other-functions.rst index 6717d16a4..d9f757cc9 100644 --- a/doc/source/ref/other-functions.rst +++ b/doc/source/ref/other-functions.rst @@ -64,12 +64,3 @@ Each can be loaded via a function of the same name. .. currentmodule:: pywt.data .. autofunction:: demo_signal - -**Example:** - -.. sourcecode:: python - - >>> import pywt - >>> camera = pywt.data.camera() - >>> doppler = pywt.data.demo_signal('doppler', 1024) - >>> available_signals = pywt.data.demo_signal('list') diff --git a/pywt/data/_wavelab_signals.py b/pywt/data/_wavelab_signals.py index 6f86856b7..823d63231 100644 --- a/pywt/data/_wavelab_signals.py +++ b/pywt/data/_wavelab_signals.py @@ -63,6 +63,16 @@ def demo_signal(name='Bumps', n=None): test signals are provided with permission of Dr. Donoho to encourage reproducible research. + Examples + -------- + >>> import pywt + >>> camera = pywt.data.camera() + >>> doppler = pywt.data.demo_signal('doppler', 1024) + >>> available_signals = pywt.data.demo_signal('list') + >>> print(available_signals) + + + """ if name.lower() == 'list': return _implemented_signals From fbb063ab875b808ab759f542091af37cf3a1b757 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Fri, 22 Mar 2024 18:04:43 +0530 Subject: [PATCH 09/11] DOC: Update SciPy intersphinx target location --- doc/source/conf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/conf.py b/doc/source/conf.py index 70ba4d222..ed40c7442 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -289,10 +289,10 @@ # -- Options for intersphinx extension --------------------------------------- -# Intersphinx to get Numpy and other targets +# Intersphinx to get NumPy, SciPy, and other targets intersphinx_mapping = { 'numpy': ('https://numpy.org/devdocs', None), - 'scipy': ('https://docs.scipy.org/doc/scipy/reference', None), + 'scipy': ('https://docs.scipy.org/doc/scipy/', None), } # -- Options for JupyterLite ------------------------------------------------- From 68a2f41df19724ccdb7ba135a2244180f5a119bf Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Fri, 22 Mar 2024 18:06:55 +0530 Subject: [PATCH 10/11] =?UTF-8?q?DOC:=20`..=20sourcecode::`=20=E2=9E=A1?= =?UTF-8?q?=EF=B8=8F=20`..try=5Fexamples::`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/source/ref/cwt.rst | 9 +++++---- doc/source/ref/signal-extension-modes.rst | 10 +++++----- doc/source/ref/wavelets.rst | 18 +++++++++--------- pywt/_cwt.py | 2 +- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/doc/source/ref/cwt.rst b/doc/source/ref/cwt.rst index 731d6705e..6971e2990 100644 --- a/doc/source/ref/cwt.rst +++ b/doc/source/ref/cwt.rst @@ -89,9 +89,10 @@ Continuous Wavelet Families A variety of continuous wavelets have been implemented. A list of the available wavelet names compatible with ``cwt`` can be obtained by: -.. sourcecode:: python +.. try_examples:: - wavlist = pywt.wavelist(kind='continuous') + >>> import pywt + >>> wavelist = pywt.wavelist(kind='continuous') Here is an overview of all available wavelets for ``cwt``. Note, that they can be customized by passing parameters such as ``center_frequency`` and ``bandwidth_frequency`` @@ -205,7 +206,7 @@ sampled at 100 Hz, a center frequency of 1.0 corresponds to ~100 Hz at ``scale = 1``. This is above the Nyquist rate of 50 Hz, so for this particular wavelet, one would analyze a signal using ``scales >= 2``. -.. sourcecode:: python +.. try_examples:: >>> import numpy as np >>> import pywt @@ -235,7 +236,7 @@ the input frequency in this function is normalized by 1/dt, or the sampling frequency fs. This function is useful for specifying the transform as a function of frequency directly. -.. sourcecode:: python +.. try_examples:: >>> import numpy as np >>> import pywt diff --git a/doc/source/ref/signal-extension-modes.rst b/doc/source/ref/signal-extension-modes.rst index 81e6ecd05..1b39e2e6f 100644 --- a/doc/source/ref/signal-extension-modes.rst +++ b/doc/source/ref/signal-extension-modes.rst @@ -87,9 +87,9 @@ computations can be performed with the `periodization`_ mode: smallest possible number of decomposition coefficients. :ref:`IDWT ` must be performed with the same mode. - **Example:** +**Example:** - .. sourcecode:: python +.. try_examples:: >>> import pywt >>> print(pywt.Modes.modes) @@ -104,7 +104,7 @@ signal to an even length prior to using periodic boundary conditions. Notice that you can use any of the following ways of passing wavelet and mode parameters: -.. sourcecode:: python +.. try_examples:: >>> import pywt >>> (a, d) = pywt.dwt([1,2,3,4,5,6], 'db2', 'smooth') @@ -142,8 +142,8 @@ Padding using PyWavelets Signal Extension Modes - ``pad`` .. autofunction:: pad -Pywavelets provides a function, :func:`pad`, that operate like -:func:`numpy.pad`, but supporting the PyWavelets signal extension modes +Pywavelets provides a function, :func:`pad`, that operates like +:func:`numpy.pad`, but supports the PyWavelets signal extension modes discussed above. For efficiency, the DWT routines in PyWavelets do not expclitly create padded signals using this function. It can be used to manually prepad signals to reduce boundary effects in functions such as :func:`cwt` and diff --git a/doc/source/ref/wavelets.rst b/doc/source/ref/wavelets.rst index 8fb692ae1..7211bb3d8 100644 --- a/doc/source/ref/wavelets.rst +++ b/doc/source/ref/wavelets.rst @@ -48,7 +48,7 @@ Custom discrete wavelets are also supported through the **Example:** - .. sourcecode:: python + .. try_examples:: >>> import pywt >>> wavelet = pywt.Wavelet('db1') @@ -128,7 +128,7 @@ Custom discrete wavelets are also supported through the **Example:** - .. sourcecode:: python + .. try_examples:: >>> def format_array(arr): ... return "[%s]" % ", ".join(["%.14f" % x for x in arr]) @@ -171,7 +171,7 @@ Approximating wavelet and scaling functions - ``Wavelet.wavefun()`` **Example:** - .. sourcecode:: python + .. try_examples:: >>> import pywt >>> wavelet = pywt.Wavelet('db2') @@ -186,7 +186,7 @@ Approximating wavelet and scaling functions - ``Wavelet.wavefun()`` **Example:** - .. sourcecode:: python + .. try_examples:: >>> import pywt >>> wavelet = pywt.Wavelet('bior3.5') @@ -239,7 +239,7 @@ from plain Python lists of filter coefficients and a *filter bank-like* object. **Example:** - .. sourcecode:: python + .. try_examples:: >>> import pywt, math >>> c = math.sqrt(2)/2 @@ -273,7 +273,7 @@ from plain Python lists of filter coefficients and a *filter bank-like* object. **Example:** - .. sourcecode:: python + .. try_examples:: >>> import pywt >>> wavelet = pywt.ContinuousWavelet('gaus1') @@ -328,7 +328,7 @@ from plain Python lists of filter coefficients and a *filter bank-like* object. **Example:** - .. sourcecode:: python + .. try_examples:: >>> import pywt >>> wavelet = pywt.ContinuousWavelet('gaus1') @@ -358,7 +358,7 @@ Approximating wavelet functions - ``ContinuousWavelet.wavefun()`` **Example:** - .. sourcecode:: python + .. try_examples:: >>> import pywt >>> wavelet = pywt.ContinuousWavelet('gaus1') @@ -375,7 +375,7 @@ Approximating wavelet functions - ``ContinuousWavelet.wavefun()`` **Example:** - .. sourcecode:: python + .. try_examples:: >>> import pywt >>> wavelet = pywt.DiscreteContinuousWavelet('db1') diff --git a/pywt/_cwt.py b/pywt/_cwt.py index e740c7e21..161c4b340 100644 --- a/pywt/_cwt.py +++ b/pywt/_cwt.py @@ -96,7 +96,7 @@ def cwt(data, scales, wavelet, sampling_period=1., method='conv', axis=-1): >>> coef, freqs=pywt.cwt(y,np.arange(1,129),'gaus1') >>> plt.matshow(coef) # doctest: +SKIP >>> plt.show() # doctest: +SKIP - ---------- + >>> import pywt >>> import numpy as np >>> import matplotlib.pyplot as plt From 7977ff80daab06d4416169ff8cdc4fb7c71b685e Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Fri, 22 Mar 2024 20:55:54 +0530 Subject: [PATCH 11/11] DOC: Add custom `:button_text:` for all examples See https://github.com/jupyterlite/jupyterlite-sphinx/issues/157 --- doc/source/ref/cwt.rst | 3 +++ doc/source/ref/signal-extension-modes.rst | 2 ++ doc/source/ref/wavelets.rst | 9 +++++++++ 3 files changed, 14 insertions(+) diff --git a/doc/source/ref/cwt.rst b/doc/source/ref/cwt.rst index 6971e2990..f0d5ab539 100644 --- a/doc/source/ref/cwt.rst +++ b/doc/source/ref/cwt.rst @@ -90,6 +90,7 @@ A variety of continuous wavelets have been implemented. A list of the available wavelet names compatible with ``cwt`` can be obtained by: .. try_examples:: + :button_text: Try it in your browser! >>> import pywt >>> wavelist = pywt.wavelist(kind='continuous') @@ -207,6 +208,7 @@ sampled at 100 Hz, a center frequency of 1.0 corresponds to ~100 Hz at particular wavelet, one would analyze a signal using ``scales >= 2``. .. try_examples:: + :button_text: Try it in your browser! >>> import numpy as np >>> import pywt @@ -237,6 +239,7 @@ frequency fs. This function is useful for specifying the transform as a function of frequency directly. .. try_examples:: + :button_text: Try it in your browser! >>> import numpy as np >>> import pywt diff --git a/doc/source/ref/signal-extension-modes.rst b/doc/source/ref/signal-extension-modes.rst index 1b39e2e6f..9ea76a66c 100644 --- a/doc/source/ref/signal-extension-modes.rst +++ b/doc/source/ref/signal-extension-modes.rst @@ -90,6 +90,7 @@ computations can be performed with the `periodization`_ mode: **Example:** .. try_examples:: + :button_text: Try it in your browser! >>> import pywt >>> print(pywt.Modes.modes) @@ -105,6 +106,7 @@ Notice that you can use any of the following ways of passing wavelet and mode parameters: .. try_examples:: + :button_text: Try it in your browser! >>> import pywt >>> (a, d) = pywt.dwt([1,2,3,4,5,6], 'db2', 'smooth') diff --git a/doc/source/ref/wavelets.rst b/doc/source/ref/wavelets.rst index 7211bb3d8..8fe6c319a 100644 --- a/doc/source/ref/wavelets.rst +++ b/doc/source/ref/wavelets.rst @@ -49,6 +49,7 @@ Custom discrete wavelets are also supported through the **Example:** .. try_examples:: + :button_text: Try it in your browser! >>> import pywt >>> wavelet = pywt.Wavelet('db1') @@ -129,6 +130,7 @@ Custom discrete wavelets are also supported through the **Example:** .. try_examples:: + :button_text: Try it in your browser! >>> def format_array(arr): ... return "[%s]" % ", ".join(["%.14f" % x for x in arr]) @@ -172,6 +174,7 @@ Approximating wavelet and scaling functions - ``Wavelet.wavefun()`` **Example:** .. try_examples:: + :button_text: Try it in your browser! >>> import pywt >>> wavelet = pywt.Wavelet('db2') @@ -187,6 +190,7 @@ Approximating wavelet and scaling functions - ``Wavelet.wavefun()`` **Example:** .. try_examples:: + :button_text: Try it in your browser! >>> import pywt >>> wavelet = pywt.Wavelet('bior3.5') @@ -240,6 +244,7 @@ from plain Python lists of filter coefficients and a *filter bank-like* object. **Example:** .. try_examples:: + :button_text: Try it in your browser! >>> import pywt, math >>> c = math.sqrt(2)/2 @@ -274,6 +279,7 @@ from plain Python lists of filter coefficients and a *filter bank-like* object. **Example:** .. try_examples:: + :button_text: Try it in your browser! >>> import pywt >>> wavelet = pywt.ContinuousWavelet('gaus1') @@ -329,6 +335,7 @@ from plain Python lists of filter coefficients and a *filter bank-like* object. **Example:** .. try_examples:: + :button_text: Try it in your browser! >>> import pywt >>> wavelet = pywt.ContinuousWavelet('gaus1') @@ -359,6 +366,7 @@ Approximating wavelet functions - ``ContinuousWavelet.wavefun()`` **Example:** .. try_examples:: + :button_text: Try it in your browser! >>> import pywt >>> wavelet = pywt.ContinuousWavelet('gaus1') @@ -376,6 +384,7 @@ Approximating wavelet functions - ``ContinuousWavelet.wavefun()`` **Example:** .. try_examples:: + :button_text: Try it in your browser! >>> import pywt >>> wavelet = pywt.DiscreteContinuousWavelet('db1')