From bfd225dfd20fcf1367a7cc9875ef4dc1442e0a2d Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Tue, 28 Nov 2017 12:42:43 -0800 Subject: [PATCH] DOC: re-organize documenting_mpl --- doc/devel/documenting_mpl.rst | 572 ++++++++++++++++++++++++---------- doc/devel/index.rst | 1 + doc/devel/plot_directive.rst | 6 + 3 files changed, 411 insertions(+), 168 deletions(-) create mode 100644 doc/devel/plot_directive.rst diff --git a/doc/devel/documenting_mpl.rst b/doc/devel/documenting_mpl.rst index 70a11f4cbb19..a896777ca92f 100644 --- a/doc/devel/documenting_mpl.rst +++ b/doc/devel/documenting_mpl.rst @@ -7,12 +7,39 @@ Writing documentation Getting started =============== + +General file structure +---------------------- + +All documentation is built from the :file:`doc/` directory. This directory +contains both reStructuredText (ReST_; ``.rst``) files that contain pages in +the documentation and configuration files for Sphinx_. + +The ``.rst`` files are kept in :file:`doc/users`, +:file:`doc/devel`, :file:`doc/api` and :file:`doc/faq`. The main entry point is +:file:`doc/index.rst`, which pulls in the :file:`index.rst` file for the users +guide, developers guide, api reference, and FAQs. The documentation suite is +built as a single document in order to make the most effective use of cross +referencing. + +Sphinx_ also creates ``.rst`` files that are staged in :file:`doc/api` from +the docstrings of the classes in the Matplotlib library. Except for +:file:`doc/api/api_changes/`, these ``.rst`` files are created when the +documentation is built. + +Similarly, the contents of :file:`docs/gallery` and :file:`docs/tutorials` are +generated by the `Sphinx Gallery`_ from the sources in :file:`examples` and +:file:`tutorials`. These sources consist of python scripts that have ReST_ +documentation built into their comments. Don't directly edit the +``.rst`` files in :file:`docs/gallery` and :file:`docs/tutorials` as they are +regenerated when the documentation are built. + Installing dependencies ----------------------- -The documentation for Matplotlib is generated from reStructuredText using -the Sphinx_ documentation generation tool. There are several extra requirements -that are needed to build the documentation. They are listed in +The documentation for Matplotlib is generated from reStructuredText (ReST_) +using the Sphinx_ documentation generation tool. There are several extra +requirements that are needed to build the documentation. They are listed in :file:`doc-requirements.txt` and listed below: * Sphinx>=1.3, !=1.5.0, !=1.6.4 @@ -30,47 +57,13 @@ that are needed to build the documentation. They are listed in * `Graphviz `_ is not a Python package, and needs to be installed separately. -General file structure ----------------------- - -All documentation is built from the :file:`doc/` directory. This directory -contains both ``.rst`` files that contain pages in the documentation and -configuration files for Sphinx_. - -The ``.rst`` files are kept in :file:`doc/users`, -:file:`doc/devel`, :file:`doc/api` and :file:`doc/faq`. The main entry point is -:file:`doc/index.rst`, which pulls in the :file:`index.rst` file for the users -guide, developers guide, api reference, and FAQs. The documentation suite is -built as a single document in order to make the most effective use of cross -referencing. - -.. note:: - - An exception to this are the directories :file:`examples` and - :file:`tutorials`, which exist in the root directory. These contain Python - files that are built by `Sphinx Gallery`_. When the docs are built, - the directories :file:`docs/gallery` and :file:`docs/tutorials` - are automatically generated. Do not edit the rst files in :file:docs/gallery - and :file:docs/tutorials, as they are rebuilt from the original sources in - the root directory. - - -Additional files can be added to the various guides by including their base -file name (the .rst extension is not necessary) in the table of contents. -It is also possible to include other documents through the use of an include -statement, such as:: - - .. include:: ../../TODO - -The configuration file for Sphinx is :file:`doc/conf.py`. It controls which -directories Sphinx parses, how the docs are built, and how the extensions are -used. - Building the docs ----------------- The documentation sources are found in the :file:`doc/` directory in the trunk. -To build the documentation in html format, cd into :file:`doc/` and run +The configuration file for Sphinx is :file:`doc/conf.py`. It controls which +directories Sphinx parses, how the docs are built, and how the extensions are +used. To build the documentation in html format, cd into :file:`doc/` and run: .. code-block:: sh @@ -106,15 +99,223 @@ html``. On Windows, options needs to be set as environment variables, e.g. ``set O=-W -j4 & make html``. -Writing new documentation -========================= +.. _writing-rest-pages: + +Writing ReST pages +================== + +Most documentation is either in the docstring of individual +classes and methods, in explicit ``.rst`` files, or in examples and tutorials. +All of these use the ReST_ syntax. Users should look at the ReST_ documentation +for a full description. But some specific hints and conventions Matplotlib +uses are useful for creating documentation. + +Formatting and style conventions +-------------------------------- + +It is useful to strive for consistency in the Matplotlib documentation. Here +are some formatting and style conventions that are used. + +Section name formatting +~~~~~~~~~~~~~~~~~~~~~~~ + +For everything but top-level chapters, use ``Upper lower`` for +section titles, e.g., ``Possible hangups`` rather than ``Possible +Hangups`` + +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: + +.. code-block:: rst + + Here is a description of *argument* + +Do not use the ```default role```: + +.. code-block:: rst + + Do not describe `argument` like this. As per the next section, + this syntax will (unsuccessfully) attempt to resolve the argument as a + link to a class or method in the library. + +nor the ````literal```` role: + +.. code-block:: rst + + Do not describe ``argument`` like this. + + +.. _internal-section-refs: + +Referring to other documents and sections +----------------------------------------- + +Sphinx_ allows internal references_ between documents. + +Documents can be linked with the `:doc:` directive: + +.. code-block:: rst + + See the :doc:`/faq/installing_faq` + + See the tutorial :doc:`/tutorials/introductory/sample_plots` + + See the example :doc:`/gallery/lines_bars_and_markers/simple_plot` + +will render as: + + See the :doc:`/faq/installing_faq` + + See the tutorial :doc:`/tutorials/introductory/sample_plots` + + See the example :doc:`/gallery/lines_bars_and_markers/simple_plot` + +Sections can also be given reference names. For instance from the +:doc:`/faq/installing_faq` link: + +.. code-block:: rst + + .. _clean-install: + + How to completely remove Matplotlib + =================================== + + Occasionally, problems with Matplotlib can be solved with a clean... + +and refer to it using the standard reference syntax: + +.. code-block:: rst + + See :ref:`clean-install` + +will give the following link: :ref:`clean-install` + +To maximize internal consistency in section labeling and references, +use hyphen separated, descriptive labels for section references. +Keep in mind that contents may be reorganized later, so +avoid top level names in references like ``user`` or ``devel`` +or ``faq`` unless necessary, because for example the FAQ "what is a +backend?" could later become part of the users guide, so the label: + +.. code-block:: rst + + .. _what-is-a-backend: + +is better than: + +.. code-block:: rst + + .. _faq-backend: + +In addition, since underscores are widely used by Sphinx itself, use +hyphens to separate words. + + +Referring to other code +----------------------- -Most 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 -https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt for more -details and a guide to how docstrings should be formatted. +To link to other methods, classes, or modules in Matplotlib you can use +back ticks, for example: + +.. code-block:: python + + `~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: + +.. code-block:: python + + `matplotlib.collections.LineCollection` + +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: + +.. code-block:: python + + `~.LineCollection` + +links just as well: `~.LineCollection`. + +Other packages can also be linked via ``intersphinx``: + +.. code-block:: Python + + `numpy.mean` + +will return this link: `numpy.mean`. This works for Python, Numpy, Scipy, +and Pandas (full list is in :file:`doc/conf.py`). 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):: + + python -m sphinx.ext.intersphinx 'https://docs.scipy.org/doc/numpy/objects.inv' + +.. _rst-figures-and-includes: + +Including figures and files +--------------------------- + +Image files can directly included in pages with the ``image::`` directive. +e.g., :file:`users/navigation_toolbar.rst` displays the toolbar icons +with a call to a static image:: + + .. image:: ../_static/toolbar.png + +as rendered on the page: :ref:`navigation-toolbar`. + +Files can be included verbatim. For instance the ``matplotlibrc`` file +is important for customizing Matplotlib, and is included verbatim in the +tutorial in :doc:`/tutorials/introductory/customizing`:: + + .. literalinclude:: ../../_static/matplotlibrc + +This is rendered as :doc:`/tutorials/introductory/customizing` (see the +bottom of the page. Note that this is in a tutorial; See +:ref:`writing-examples-and-tutorials` below) + +In the top level :file:`doc` directory there are symlinks pointing to the +Matplotlib :file:`examples`: + +.. code-block:: sh + + home:~/mpl/doc> ls -l mpl_* + mpl_examples -> ../examples + +Plots are included from the examples dir using the symlink: + +.. code-block:: rst + + .. plot:: mpl_examples/pylab_examples/simple_plot.py + +Note that the python script that generates the plot is referred to, rather +than any plot that is created. `Sphinx Gallery`_ will provide the incorrect +reference when the documentation is built. + + +.. _writing-docstrings: + +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 +:file:`doc/api` directory and form the reference documentation for the +library. + +Example docstring +----------------- An example docstring looks like: @@ -154,7 +355,9 @@ An example docstring looks like: axhline: horizontal line across the axes """ -The Sphinx website also contains plenty of documentation_ concerning ReST +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:: @@ -164,14 +367,15 @@ markup and working with Sphinx in general. you may see in the source code. Pull requests updating docstrings to the current style are very welcome. -Additional formatting conventions ---------------------------------- +Formatting conventions +---------------------- -There are some additional conventions, not handled by numpydoc and the Sphinx -guide: +The basic docstring conventions are covered in the `numpy documentation howto`_ +and the Sphinx_ documentation. Some Matplotlib-specific formatting conventions +to keep in mind: -* We do not have a convention whether to use single-quotes or double-quotes. - There is a mixture of both in the current code. Please leave them as they are. +* Matplotlib does not have a convention whether to use single-quotes or + double-quotes. There is a mixture of both in the current code. * Long parameter lists should be wrapped using a ``\`` for continuation and starting on the new line without any indent: @@ -188,6 +392,7 @@ guide: ['aitoff' | 'hammer' | 'lambert' | 'mollweide' | \ 'polar' | 'rectilinear'], optional The projection type of the axes. + """ ... """ @@ -233,27 +438,30 @@ with Python's documentation: Here is a description of *argument* -Please do not use the ```default role```: +Do not use the ```default role```: .. code-block:: rst - Please do not describe `argument` like this. + Do not describe `argument` like this. nor the ````literal```` role: .. code-block:: rst - Please do not describe ``argument`` like this. + Do not describe ``argument`` like this. Setters and getters ------------------- -Matplotlib uses artist introspection of docstrings to support properties. -All properties that you want to support through `~.pyplot.setp` and -`~.pyplot.getp` should have a ``set_property`` and ``get_property`` method in -the `~.matplotlib.artist.Artist` class. The setter methods use the docstring -with the ACCEPTS token to indicate the type of argument the method accepts. -e.g., in `.Line2D`: + +Artist properties are implemented using setter and getter methods (because +Matplotlib predates the introductions of the `property` decorator in Python). +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. + +Property setter methods should indicate the values they accept using a (legacy) +special block in the docstring, starting with ``ACCEPTS``, as follows: .. code-block:: python @@ -265,8 +473,21 @@ e.g., in `.Line2D`: ACCEPTS: [ '-' | '--' | '-.' | ':' | 'steps' | 'None' | ' ' | '' ] """ +The ACCEPTS block is used to render a table of all properties and their +acceptable values in the docs; it can also be displayed using, e.g., +``plt.setp(Line2D)`` (all properties) or ``plt.setp(Line2D, 'linestyle')`` +(just one property). + Keyword arguments ----------------- + +.. note:: + + The information in this section is being actively discussed by the + development team, so use the docstring interpolation only if necessary. + This section has been left in place for now because this interpolation + is part of the existing documentation. + Since Matplotlib uses a lot of pass-through ``kwargs``, e.g., in every function that creates a line (`~.pyplot.plot`, `~.pyplot.semilogx`, `~.pyplot.semilogy`, etc...), it can be difficult for the new user to know which ``kwargs`` are @@ -321,156 +542,168 @@ definition. There are some some manual hacks in this case, violating the "single entry point" requirement above -- see the ``docstring.interpd.update`` calls in `matplotlib.patches`. -Adding figures -============== - -Figures in the documentation are automatically generated from scripts. -It is not necessary to explicitly save the figure from the script; this will be -done automatically when the docs are built to ensure that the code that is -included runs and produces the advertised figure. +.. _docstring-adding-figures: -There are two options for where to put the code that generates a figure. If -you want to include a plot in the examples gallery, the code should be added to -the :file:`examples` directory. Plots from -the :file:`examples` directory can then be referenced through the symlink -``mpl_examples`` in the ``doc`` directory, e.g.: - -.. code-block:: rst +Adding figures +-------------- - .. plot:: mpl_examples/lines_bars_and_markers/fill.py +As above (see :ref:`rst-figures-and-includes`), figures in the examples gallery +can be referenced with a `:plot:` directive pointing to the python script that +created the figure. For instance the `~.Axes.legend` docstring references +the file :file:`examples/api/legend.py`: -Alternatively the plotting code can be placed directly in the docstring. -To include plots directly in docstrings, see the following guide: +.. code-block:: python -Plot directive documentation ----------------------------- + """ + ... -.. automodule:: matplotlib.sphinxext.plot_directive - :no-undoc-members: + Examples + -------- -Examples --------- + .. plot:: gallery/api/legend.py + """ -The source of the files in the :file:`examples` directory are automatically run -and their output plots included in the documentation. To exclude an example -from having an plot generated insert "sgskip" somewhere in the filename. +Note that ``examples/api/legend.py`` has been mapped to +``gallery/api/legend.py``, a redirection that may be fixed in future +re-organization of the docs. -Adding animations -================= - -We have a Matplotlib Google/Gmail account with username ``mplgithub`` -which we used to setup the github account but can be used for other -purposes, like hosting Google docs or Youtube videos. You can embed a -Matplotlib animation in the docs by first saving the animation as a -movie using :meth:`matplotlib.animation.Animation.save`, and then -uploading to `matplotlib's Youtube -channel `_ and inserting the -embedding string youtube provides like: +Plots can also be directly placed inside docstrings. Details are in +:doc:`/devel/plot_directive`. A short example is: -.. code-block:: rst +.. code-block:: python - .. raw:: html + """ + ... - + Examples + -------- -An example save command to generate a movie looks like this + .. plot:: + import matplotlib.image as mpimg + img = mpimg.imread('_static/stinkbug.png') + imgplot = plt.imshow(img) + """ -.. code-block:: python +An advantage of this style over referencing an example script is that the +code will also appear in interactive docstrings. - ani = animation.FuncAnimation(fig, animate, np.arange(1, len(y)), - interval=25, blit=True, init_func=init) +.. _writing-examples-and-tutorials: - ani.save('double_pendulum.mp4', fps=15) +Writing examples and tutorials +============================== -Contact Michael Droettboom for the login password to upload youtube videos of -google docs to the mplgithub account. +Examples and tutorials are python scripts that are run by `Sphinx Gallery`_ +to create a gallery of images in the :file:`/doc/gallery` and +:file:`/doc/tutorials` directories respectively. To exclude an example +from having an plot generated insert "sgskip" somewhere in the filename. -.. _referring-to-mpl-docs: +The format of these files is relatively straightforward. Properly +formatted comment blocks are treated as ReST_ text, the code is +displayed, and figures are put into the built page. -Referring to data files -======================= +For instance the example :doc:`/gallery/lines_bars_and_markers/simple_plot` +example is generated from +:file:`/examples/lines_bars_and_markers/simple_plot.py`, which looks like: -In the documentation, you may want to include to a data file in the Matplotlib -sources, e.g., a license file or an image file from :file:`mpl-data`, refer to it via -a relative path from the document where the rst file resides, e.g., -in :file:`users/navigation_toolbar.rst`, you can refer to the image icons with:: +.. code-block:: python - .. image:: ../../lib/matplotlib/mpl-data/images/subplots.png + """ + =========== + Simple Plot + =========== -In the :file:`users` subdirectory, if you want to refer to a file in the -:file:`mpl-data` directory, you can use the symlink directory. For example, -from :file:`customizing.rst`:: + Create a simple plot. + """ + import matplotlib.pyplot as plt + import numpy as np - .. literalinclude:: ../../lib/matplotlib/mpl-data/matplotlibrc + # Data for plotting + t = np.arange(0.0, 2.0, 0.01) + s = 1 + np.sin(2 * np.pi * t) -One exception to this is when referring to the examples directory. Relative -paths are extremely confusing in the sphinx plot extensions, so it is easier -to simply include a symlink to the files at the top doc level directory. -This way, API documents like :meth:`matplotlib.pyplot.plot` can refer to the -examples in a known location. + # Note that using plt.subplots below is equivalent to using + # fig = plt.figure and then ax = fig.add_subplot(111) + fig, ax = plt.subplots() + ax.plot(t, s) -In the top level :file:`doc` directory we have symlinks pointing to the -Matplotlib :file:`examples`: + ax.set(xlabel='time (s)', ylabel='voltage (mV)', + title='About as simple as it gets, folks') + ax.grid() + plt.show() -.. code-block:: sh +The first comment block is treated as ReST_ text. The other comment blocks +render as comments in :doc:`/gallery/lines_bars_and_markers/simple_plot`. - home:~/mpl/doc> ls -l mpl_* - mpl_examples -> ../examples +Tutorials are made with the exact same mechanism, except they are longer, and +typically have more than one comment block (i.e. +:doc:`/tutorials/introductory/usage`). The first comment block +can be the same as the example above. Subsequent blocks of ReST text +are delimited by a line of `###` characters: -So we can include plots from the examples dir using the symlink: +.. code-block:: python -.. code-block:: rst + """ + =========== + Simple Plot + =========== - .. plot:: mpl_examples/pylab_examples/simple_plot.py + Create a simple plot. + """ + ... + ax.grid() + plt.show() -.. _internal-section-refs: + ########################################################################## + # Second plot + # =========== + # + # This is a second plot that is very nice -Internal section references -=========================== + fig, ax = plt.subplots() + ax.plot(np.sin(range(50))) -To maximize internal consistency in section labeling and references, -use hyphen separated, descriptive labels for section references, e.g.: +In this way text, code, and figures are output in a "notebook" style. -.. code-block:: rst +Miscellaneous +============= - .. _howto-webapp: +Adding animations +----------------- -and refer to it using the standard reference syntax: +There is a Matplotlib Google/Gmail account with username ``mplgithub`` +which was used to setup the github account but can be used for other +purposes, like hosting Google docs or Youtube videos. You can embed a +Matplotlib animation in the docs by first saving the animation as a +movie using :meth:`matplotlib.animation.Animation.save`, and then +uploading to `matplotlib's Youtube +channel `_ and inserting the +embedding string youtube provides like: .. code-block:: rst - See :ref:`howto-webapp` - -Keep in mind that we may want to reorganize the contents later, so -please try to avoid top level names in references like ``user`` or ``devel`` -or ``faq`` unless necessary, because for example the FAQ "what is a -backend?" could later become part of the users guide, so the label: - -.. code-block:: rst + .. raw:: html - .. _what-is-a-backend + -is better than: +An example save command to generate a movie looks like this -.. code-block:: rst +.. code-block:: python - .. _faq-backend + ani = animation.FuncAnimation(fig, animate, np.arange(1, len(y)), + interval=25, blit=True, init_func=init) -In addition, since underscores are widely used by Sphinx itself, please use -hyphens to separate words. + ani.save('double_pendulum.mp4', fps=15) -Section name formatting -======================= +Contact Michael Droettboom for the login password to upload youtube videos of +google docs to the mplgithub account. -For everything but top level chapters, please use ``Upper lower`` for -section titles, e.g., ``Possible hangups`` rather than ``Possible -Hangups`` +.. _inheritance-diagrams: Generating inheritance diagrams -=============================== +------------------------------- Class inheritance diagrams can be generated with the ``inheritance-diagram`` directive. To use it, provide the @@ -498,7 +731,7 @@ Example: .. _emacs-helpers: Emacs helpers -============= +------------- There is an emacs mode `rst.el `_ which @@ -534,8 +767,11 @@ Some helpful functions:: .. TODO: Add section about uploading docs +.. _ReST: http://docutils.sourceforge.net/rst.html .. _Sphinx: http://www.sphinx-doc.org .. _documentation: http://www.sphinx-doc.org/contents.html .. _`inline markup`: http://www.sphinx-doc.org/markup/inline.html .. _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 diff --git a/doc/devel/index.rst b/doc/devel/index.rst index 118f1f564db3..798127a698c3 100644 --- a/doc/devel/index.rst +++ b/doc/devel/index.rst @@ -15,6 +15,7 @@ The Matplotlib Developers' Guide contributing.rst testing.rst documenting_mpl.rst + plot_directive.rst add_new_projection.rst portable_code.rst gitwash/index.rst diff --git a/doc/devel/plot_directive.rst b/doc/devel/plot_directive.rst new file mode 100644 index 000000000000..df0938324f20 --- /dev/null +++ b/doc/devel/plot_directive.rst @@ -0,0 +1,6 @@ +============================ +Plot directive documentation +============================ + +.. automodule:: matplotlib.sphinxext.plot_directive + :no-undoc-members: