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 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 647d34a34..ed40c7442 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', @@ -193,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' @@ -282,8 +289,22 @@ # -- 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 ------------------------------------------------- + +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).""" +) diff --git a/doc/source/ref/cwt.rst b/doc/source/ref/cwt.rst index 731d6705e..f0d5ab539 100644 --- a/doc/source/ref/cwt.rst +++ b/doc/source/ref/cwt.rst @@ -89,9 +89,11 @@ 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:: + :button_text: Try it in your browser! - 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 +207,8 @@ 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:: + :button_text: Try it in your browser! >>> import numpy as np >>> import pywt @@ -235,7 +238,8 @@ 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:: + :button_text: Try it in your browser! >>> import numpy as np >>> import pywt 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/doc/source/ref/signal-extension-modes.rst b/doc/source/ref/signal-extension-modes.rst index 81e6ecd05..9ea76a66c 100644 --- a/doc/source/ref/signal-extension-modes.rst +++ b/doc/source/ref/signal-extension-modes.rst @@ -87,9 +87,10 @@ 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:: + :button_text: Try it in your browser! >>> import pywt >>> print(pywt.Modes.modes) @@ -104,7 +105,8 @@ 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:: + :button_text: Try it in your browser! >>> import pywt >>> (a, d) = pywt.dwt([1,2,3,4,5,6], 'db2', 'smooth') @@ -142,8 +144,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..8fe6c319a 100644 --- a/doc/source/ref/wavelets.rst +++ b/doc/source/ref/wavelets.rst @@ -48,7 +48,8 @@ Custom discrete wavelets are also supported through the **Example:** - .. sourcecode:: python + .. try_examples:: + :button_text: Try it in your browser! >>> import pywt >>> wavelet = pywt.Wavelet('db1') @@ -128,7 +129,8 @@ Custom discrete wavelets are also supported through the **Example:** - .. sourcecode:: python + .. try_examples:: + :button_text: Try it in your browser! >>> def format_array(arr): ... return "[%s]" % ", ".join(["%.14f" % x for x in arr]) @@ -171,7 +173,8 @@ Approximating wavelet and scaling functions - ``Wavelet.wavefun()`` **Example:** - .. sourcecode:: python + .. try_examples:: + :button_text: Try it in your browser! >>> import pywt >>> wavelet = pywt.Wavelet('db2') @@ -186,7 +189,8 @@ Approximating wavelet and scaling functions - ``Wavelet.wavefun()`` **Example:** - .. sourcecode:: python + .. try_examples:: + :button_text: Try it in your browser! >>> import pywt >>> wavelet = pywt.Wavelet('bior3.5') @@ -239,7 +243,8 @@ from plain Python lists of filter coefficients and a *filter bank-like* object. **Example:** - .. sourcecode:: python + .. try_examples:: + :button_text: Try it in your browser! >>> import pywt, math >>> c = math.sqrt(2)/2 @@ -273,7 +278,8 @@ from plain Python lists of filter coefficients and a *filter bank-like* object. **Example:** - .. sourcecode:: python + .. try_examples:: + :button_text: Try it in your browser! >>> import pywt >>> wavelet = pywt.ContinuousWavelet('gaus1') @@ -328,7 +334,8 @@ from plain Python lists of filter coefficients and a *filter bank-like* object. **Example:** - .. sourcecode:: python + .. try_examples:: + :button_text: Try it in your browser! >>> import pywt >>> wavelet = pywt.ContinuousWavelet('gaus1') @@ -358,7 +365,8 @@ Approximating wavelet functions - ``ContinuousWavelet.wavefun()`` **Example:** - .. sourcecode:: python + .. try_examples:: + :button_text: Try it in your browser! >>> import pywt >>> wavelet = pywt.ContinuousWavelet('gaus1') @@ -375,7 +383,8 @@ Approximating wavelet functions - ``ContinuousWavelet.wavefun()`` **Example:** - .. sourcecode:: python + .. try_examples:: + :button_text: Try it in your browser! >>> import pywt >>> wavelet = pywt.DiscreteContinuousWavelet('db1') 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" +} 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 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 diff --git a/util/readthedocs/requirements.txt b/util/readthedocs/requirements.txt index 9ac8577c2..9d7d537f1 100644 --- a/util/readthedocs/requirements.txt +++ b/util/readthedocs/requirements.txt @@ -1,5 +1,7 @@ cython docutils<0.18 +jupyterlite-sphinx +jupyterlite-pyodide-kernel pydata-sphinx-theme pytest matplotlib