From f69180aeabbe3c09f9c7dcdf42d24671d2bd472c Mon Sep 17 00:00:00 2001 From: Andrew McCluskey Date: Thu, 23 Apr 2020 08:35:37 +0100 Subject: [PATCH] improving distribution docs --- docs/source/conf.py | 7 ++++- docs/source/faq.rst | 21 ++++++++++++++ docs/source/index.rst | 1 + uravu/distribution.py | 64 ++++++++++++++++++------------------------- 4 files changed, 55 insertions(+), 38 deletions(-) create mode 100644 docs/source/faq.rst diff --git a/docs/source/conf.py b/docs/source/conf.py index fe265eb..610e2f8 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -179,7 +179,6 @@ html_logo = "logo/uravu_logo.png" html_theme_options = {"logo_only": True} - # -- Extension configuration ------------------------------------------------- # -- Options for todo extension ---------------------------------------------- @@ -189,3 +188,9 @@ def setup(app): app.add_css_file('custom.css') + +# Looks for objects in external projects +intersphinx_mapping = { + 'pint': ('https://pint.readthedocs.io/en/0.11/', None), + 'scipy': ('https://docs.scipy.org/doc/scipy/reference/', None), +} diff --git a/docs/source/faq.rst b/docs/source/faq.rst new file mode 100644 index 0000000..cd9a2e9 --- /dev/null +++ b/docs/source/faq.rst @@ -0,0 +1,21 @@ +FAQ +=== + +- How does one assign units to a :py:class:`~uravu.distribution.Distribution` object? + + :py:mod:`~uravu` allows the use of the :py:mod:`~pint` module for the definition of units to be associated with :py:class:`~uravu.distribution.Distribution` objects. + The :func:`uravu.distribution.Distribution.__init__()` function includes a keyword argument :py:attr:`unit` where the :py:class:`~pint.unit.Unit` object should be assigned. + However, to `avoid creating multiple unit registries`_, :py:mod:`~uravu` is packaged with a :py:class:`~pint.UnitRegistry`. + Therefore, if you wish to create a :py:class:`~uravu.distribution.Distribution` where the :py:attr:`unit` is metres, the following syntax should be used. + +.. code-block:: python + + import numpy as np + from uravu import UREG + from uravu.distribution import Distribution + + sample = np.random.randn(100) + my_distribution = Distribution(sample, name='Random Distribution', units=UREG.meter) + + +.. _avoid creating multiple unit registries: https://pint.readthedocs.io/en/0.11/tutorial.html#using-pint-in-your-projects \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst index 7705d03..6247534 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -58,6 +58,7 @@ To see which publications you should reference in your work, the :class:`Relatio installation getting_started.ipynb tutorials + faq api Searching diff --git a/uravu/distribution.py b/uravu/distribution.py index 377ea40..24afbef 100644 --- a/uravu/distribution.py +++ b/uravu/distribution.py @@ -1,6 +1,6 @@ """ -The Distribution class allows the storage and analysis of probability -distributions. +The storage and manipulation of probability distributions is fundamental to the operation of ``uravu`` and Bayesian inference. +The :py:class:`~uravu.distribution.Distribution` class oversees these operations. """ # Copyright (c) Andrew R. McCluskey @@ -15,27 +15,22 @@ class Distribution: """ - The storage of probability distributions is fundamental to Bayesian - inference, this class enables this. In addition to storage some basic - analysis of the distribution is possible. + In addition to storage of the probability distribution, this class allows for some basic analysis, such as determination of normality. Attributes: - samples (array_like): Samples in the distribution. - name (str): A name for the distribution. - ci_points (array_like): The percentiles at which - confidence intervals should be found. - unit (pint.UnitRegistry()): The unit of the values in the - Distribution. + samples (:py:attr:`array_like`): Samples in the distribution. + name (:py:attr:`str`): Distribution name. + ci_points (:py:attr:`array_like`): The percentiles at which confidence intervals should be found. + unit (:py:class:`~pint.unit.Unit`): The unit of the values in the Distribution. + normal (:py:attr:`bool`): Are the samples normally distributed? Args: - samples (array_like): Sample for the distribution. - name (str, optional): A name to identify the distribution. - Default is `Distribution`. - ci_points (array_like, optional): The percentiles at which - confidence intervals should be found. Default is - `[2.5, 97.5]` (a 95 % confidence interval). - unit (pint.UnitRegistry(), optional) The unit for the - distribution. Default is dimensionless. + samples (:py:attr:`array_like`): Sample for the distribution. + name (:py:attr:`str`, optional): A name to identify the distribution. Default is :py:attr:`'Distribution'`. + ci_points (:py:attr:`array_like`, optional): The two percentiles at which confidence intervals should be found. Default is :py:attr:`[2.5, 97.5]` (a 95 % confidence interval). + unit (:py:class:`~pint.unit.Unit`, optional): The unit for the distribution. For information about unit assignment see the `FAQ`_. Default is :py:attr:`~pint.unit.Unit.dimensionless`. + + .. _FAQ: ./faq.html """ def __init__( @@ -46,7 +41,7 @@ def __init__( unit=UREG.dimensionless, ): """ - Initialisation function for a ``Distribution`` object. + Initialisation function for a :py:class:`~uravu.distribution.Distribution` object. """ self.name = name self.unit = unit @@ -68,14 +63,13 @@ def size(self): Get the number of samples in the distribution. Returns: - (int): Number of samples. + :py:attr:`int`: Number of samples. """ return self.samples.size def check_normality(self): """ - Uses a Shapiro-Wilks statistical test to evaluate if samples are - normally distributed. + Uses a :func:`scipy.stats.normaltest()` to evaluate if samples are normally distributed and updates the :py:attr:`~uravu.distribution.Distribution.normal` attribute. """ alpha = 0.05 if self.size <= 8: @@ -92,22 +86,20 @@ def check_normality(self): @property def n(self): """ - Get the median value of the distribution (for a normal distribution - this is the same as the mean). + Get the median value of the distribution (for a normal distribution this is the same as the mean). Returns: - (float): Median value. + :py:attr:`float`: Median value. """ return np.percentile(self.samples, [50])[0] @property def s(self): """ - Get the standard deviation of the distribution. For a non-normal - distribution, this will return ``None``. + Get the standard deviation of the distribution. For a non-normal distribution, this will return :py:attr:`None`. Returns: - (float, or None): Standard deviation of the distribution. + :py:attr:`float` or :py:attr:`None`: Standard deviation of the distribution. """ if self.normal: return np.std(self.samples) @@ -120,17 +112,16 @@ def con_int(self): Get the extrema of the confidence intervals of the distribution. Returns: - (array_like): The confidence interval values. + :py:attr:`array_like`: Distribution values at the confidence interval. """ return np.percentile(self.samples, self.ci_points) def __repr__(self): """ - A custom representation, which is the same as the custom string - representation. + A custom representation, which is the same as the custom string representation. Returns: - (str): String representation. + :py:attr:`str`: Description of the distribution. """ return self.__str__() @@ -139,7 +130,7 @@ def __str__(self): A custom string. Returns: - (str): Detailed string representation. + :py:attr:`str`: Description of the distribution. """ representation = "Distribution: {}\nSize: {}\n".format( self.name, self.size @@ -177,11 +168,10 @@ def __str__(self): def add_samples(self, samples): """ - Add samples to the distribution and update values such as median and - uncertainties as appropriate. + Add samples to the distribution. Args: - samples (array_like): Samples to be added to the distribution. + samples (:py:attr:`array_like`): Samples to be added to the distribution. """ self.samples = np.append(self.samples, np.array(samples).flatten()) self.check_normality()