Skip to content

Backport PR #11495 on branch v2.2.x (Update the documentation guidelines) #16139

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
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
4 changes: 4 additions & 0 deletions doc/_static/mpl.css
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ dl.glossary dt {
font-size: 1.1em;
}

dl.docutils dt {
font-weight: bold;
}

pre a {
color: inherit;
text-decoration: none;
Expand Down
255 changes: 160 additions & 95 deletions doc/devel/documenting_mpl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@
Writing documentation
=====================

.. contents:: Contents
:depth: 2
:local:
:backlinks: top
:class: multicol-toc


Getting started
===============

Expand Down Expand Up @@ -214,38 +221,52 @@ is better than:
In addition, since underscores are widely used by Sphinx itself, use
hyphens to separate words.

.. _referring-to-other-code:

Referring to other code
-----------------------

To link to other methods, classes, or modules in Matplotlib you can use
back ticks, for example:

.. code-block:: python
.. code-block:: rst

`~matplotlib.collections.LineCollection`
`matplotlib.collections.LineCollection`

returns a link to the documentation of
`~matplotlib.collections.LineCollection`. For the full path of the
class to be shown, omit the tilde:
generates a link like this: `matplotlib.collections.LineCollection`.

.. code-block:: python
*Note:* We use the sphinx setting ``default_role = 'obj'`` so that you don't
have to use qualifiers like ``:class:``, ``:func:``, ``:meth:`` and the likes.

`matplotlib.collections.LineCollection`
Often, you don't want to show the full package and module name. As long as the
target is unanbigous you can simply leave them out:

.. code-block:: rst

to get `matplotlib.collections.LineCollection`. It is often not
necessary to fully specify the class hierarchy unless there is a namespace
collision between two packages:
`.LineCollection`

.. code-block:: python
and the link still works: `.LineCollection`.

If there are multiple code elements with the same name (e.g. ``plot()`` is a
method in multiple classes), you'll have to extend the definition:

.. code-block:: rst

`.pyplot.plot` or `.Axes.plot`

These will show up as `.pyplot.plot` or `.Axes.plot`. To still show only the
last segment you can add a tilde as prefix:

.. code-block:: rst

`~.LineCollection`
`~.pyplot.plot` or `~.Axes.plot`

links just as well: `~.LineCollection`.
will render as `~.pyplot.plot` or `~.Axes.plot`.

Other packages can also be linked via ``intersphinx``:
Other packages can also be linked via
`intersphinx <http://www.sphinx-doc.org/en/master/ext/intersphinx.html>`_:

.. code-block:: Python
.. code-block:: rst

`numpy.mean`

Expand Down Expand Up @@ -297,13 +318,19 @@ when the documentation is built.
Writing docstrings
==================

Much of the documentation lives in "docstrings". These are comment blocks
in source code that explain how the code works. All new or edited docstrings
should conform to the numpydoc guidelines. These split the docstring into a
number of sections - see the `numpy documentation howto`_
for more details and a guide to how docstrings should be formatted. Much of
the ReST_ syntax discussed above (:ref:writing-rest-pages) can be used for
links and references. These docstrings eventually populate the
Most of the API documentation is written in docstrings. These are comment
blocks in source code that explain how the code works.

.. note::

Some parts of the documentation do not yet conform to the current
documentation style. If in doubt, follow the rules given here and not what
you may see in the source code. Pull requests updating docstrings to
the current style are very welcome.

All new or edited docstrings should conform to the `numpydoc docstring guide`_.
Much of the ReST_ syntax discussed above (:ref:`writing-rest-pages`) can be
used for links and references. These docstrings eventually populate the
:file:`doc/api` directory and form the reference documentation for the
library.

Expand All @@ -314,21 +341,21 @@ An example docstring looks like:

.. code-block:: python

def hlines(self, y, xmin, xmax, colors='k', linestyles='solid',
label='', **kwargs):
def hlines(self, y, xmin, xmax, colors='k', linestyles='solid',
label='', **kwargs):
"""
Plot horizontal lines at each *y* from *xmin* to *xmax*.

Parameters
----------
y : scalar or sequence of scalar
y : float or array-like
y-indexes where to plot the lines.

xmin, xmax : scalar or 1D array_like
xmin, xmax : float or array-like
Respective beginning and end of each line. If scalars are
provided, all lines will have same length.
provided, all lines will have the same length.

colors : array_like of colors, optional, default: 'k'
colors : array-like of colors, optional, default: 'k'

linestyles : {'solid', 'dashed', 'dashdot', 'dotted'}, optional

Expand All @@ -353,104 +380,137 @@ See the `~.Axes.hlines` documentation for how this renders.
The Sphinx_ website also contains plenty of documentation_ concerning ReST
markup and working with Sphinx in general.

.. note::

Some parts of the documentation do not yet conform to the current
documentation style. If in doubt, follow the rules given here and not what
you may see in the source code. Pull requests updating docstrings to
the current style are very welcome.

Formatting conventions
----------------------

The basic docstring conventions are covered in the `numpy documentation howto`_
The basic docstring conventions are covered in the `numpydoc docstring guide`_
and the Sphinx_ documentation. Some Matplotlib-specific formatting conventions
to keep in mind:

* Matplotlib does not have a convention whether to use single-quotes or
double-quotes. There is a mixture of both in the current code.
Function arguments
Function arguments and keywords within docstrings should be referred to
using the ``*emphasis*`` role. This will keep Matplotlib's documentation
consistent with Python's documentation:

* Long parameter lists should be wrapped using a ``\`` for continuation and
starting on the new line without any indent:
.. code-block:: rst

.. code-block:: python
If *linestyles* is *None*, the 'solid' is used.

def add_axes(self, *args, **kwargs):
"""
...
Do not use the ```default role``` or the ````literal```` role:

Parameters
----------
projection :
{'aitoff', 'hammer', 'lambert', 'mollweide', 'polar', \
'rectilinear'}, optional
The projection type of the axes.
.. code-block:: rst

...
"""
Neither `argument` nor ``argument`` should be used.

Alternatively, you can describe the valid parameter values in a dedicated
section of the docstring.

* Generally, do not add markup to types for ``Parameters`` and ``Returns``.
This is usually not needed because Sphinx will link them automatically and
would unnecessarily clutter the docstring. However, it does seem to fail in
some situations. If you encounter such a case, you are allowed to add markup:
Quotes for strings
Matplotlib does not have a convention whether to use single-quotes or
double-quotes. There is a mixture of both in the current code.

.. code-block:: rst
Use simple single or double quotes when giving string values, e.g.:: rst

Returns
-------
lines : `~matplotlib.collections.LineCollection`
.. code-block:: rst

* rcParams can be referenced with the custom ``:rc:`` role:
:literal:`:rc:\`foo\`` yields ``rcParams["foo"]``.
If 'tight', try to figure out the tight bbox of the figure.

Deprecated formatting conventions
---------------------------------
* Formerly, we have used square brackets for explicit parameter lists
``['solid' | 'dashed' | 'dotted']``. With numpydoc we have switched to their
standard using curly braces ``{'solid', 'dashed', 'dotted'}``.
Parameter type descriptions
The main goal for parameter type descriptions is to be readable and
understandable by humans. If the possible types are too complex use a
simplification for the type description and explain the type more
precisely in the text.

Linking to other code
---------------------
To link to other methods, classes, or modules in Matplotlib you can encase
the name to refer to in back ticks, for example:
Generally, the `numpydoc docstring guide`_ conventions apply. The following
rules expand on them where the numpydoc conventions are not specific.

.. code-block:: python
Use ``float`` for a type that can be any number.

`~matplotlib.collections.LineCollection`
Use ``array-like`` for homogeneous numeric sequences, which could
typically be a numpy.array. Dimensionality may be specified using ``2D``,
``3D``, ``n-dimensional``. If you need to have variables denoting the
sizes of the dimensions, use capital letters in brackets
(``array-like (M, N)``). When refering to them in the text they are easier
read and no special formatting is needed.

It is also possible to add links to code in Python, Numpy, Scipy, or Pandas.
Sometimes it is tricky to get external Sphinx linking to work; to check that
a something exists to link to the following shell command outputs a list of all
objects that can be referenced (in this case for Numpy)::
``float`` is the implicit default dtype for array-likes. For other dtypes
use ``array-like of int``.

python -m sphinx.ext.intersphinx 'https://docs.scipy.org/doc/numpy/objects.inv'
Some possible uses::

2D array-like
array-like (N)
array-like (M, N)
array-like (M, N, 3)
array-like of int

Function arguments
------------------
Function arguments and keywords within docstrings should be referred to using
the ``*emphasis*`` role. This will keep Matplotlib's documentation consistent
with Python's documentation:
Non-numeric homogeneous sequences are described as lists, e.g.::

.. code-block:: rst
list of str
list of `.Artist`

Here is a description of *argument*
Referencing types
Generally, the rules from referring-to-other-code_ apply. More specifically:

Do not use the ```default role```:
Use full references ```~matplotlib.colors.Normalize``` with an
abbreviation tilde in parameter types. While the full name helps the
reader of plain text docstrings, the HTML does not need to show the full
name as it links to it. Hence, the ``~``-shortening keeps it more readable.

Use abbreviated links ```.Normalize``` in the text.

.. code-block:: rst
.. code-block:: rst

Do not describe `argument` like this.
norm : `~matplotlib.colors.Normalize`, optional
A `.Normalize` instance is used to scale luminance data to 0, 1.

nor the ````literal```` role:
``See also`` sections
Sphinx automatically links code elements in the definition blocks of ``See
also`` sections. No need to use backticks there::

.. code-block:: rst
See also
--------
vlines : vertical lines
axhline: horizontal line across the axes

Do not describe ``argument`` like this.
Wrapping parameter lists
Long parameter lists should be wrapped using a ``\`` for continuation and
starting on the new line without any indent:

.. code-block:: python

def add_axes(self, *args, **kwargs):
"""
...

Parameters
----------
projection :
{'aitoff', 'hammer', 'lambert', 'mollweide', 'polar', \
'rectilinear'}, optional
The projection type of the axes.

...
"""

Alternatively, you can describe the valid parameter values in a dedicated
section of the docstring.

rcParams
rcParams can be referenced with the custom ``:rc:`` role:
:literal:`:rc:\`foo\`` yields ``rcParams["foo"]``. Use `= [default-val]`
to indicate the default value of the parameter. The default value should be
literal, i.e. enclosed in double backticks. For simplicity these may be
omitted for string default values.

.. code-block:: rst

If not provided, defaults to :rc:`figure.figsize` = ``[6.4, 4.8]``.
If not provided, defaults to :rc:`figure.facecolor` = 'w'.

Deprecated formatting conventions
---------------------------------
Formerly, we have used square brackets for explicit parameter lists
``['solid' | 'dashed' | 'dotted']``. With numpydoc we have switched to their
standard using curly braces ``{'solid', 'dashed', 'dotted'}``.

Setters and getters
-------------------
Expand All @@ -461,6 +521,12 @@ By convention, these setters and getters are named ``set_PROPERTYNAME`` and
``get_PROPERTYNAME``; the list of properties thusly defined on an artist and
their values can be listed by the `~.pyplot.setp` and `~.pyplot.getp` functions.

.. note::

``ACCEPTS`` blocks have recently become optional. You may now use a
numpydoc ``Parameters`` block because the accepted values can now be read
from the type description of the first parameter.

Property setter methods should indicate the values they accept using a (legacy)
special block in the docstring, starting with ``ACCEPTS``, as follows:

Expand Down Expand Up @@ -494,7 +560,6 @@ Sphinx by making it a ReST comment (i.e. use ``.. ACCEPTS:``):
"""



Keyword arguments
-----------------

Expand Down Expand Up @@ -791,4 +856,4 @@ Some helpful functions::
.. _index: http://www.sphinx-doc.org/markup/para.html#index-generating-markup
.. _`Sphinx Gallery`: https://sphinx-gallery.readthedocs.io/en/latest/
.. _references: http://www.sphinx-doc.org/en/stable/markup/inline.html
.. _`numpy documentation howto`: https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
.. _`numpydoc docstring guide`: https://numpydoc.readthedocs.io/en/latest/format.html