diff --git a/doc/devel/documenting_mpl.rst b/doc/devel/documenting_mpl.rst index cfb08a6d28ba..c0222ffead54 100644 --- a/doc/devel/documenting_mpl.rst +++ b/doc/devel/documenting_mpl.rst @@ -1,8 +1,8 @@ .. _documenting-matplotlib: -=========================================== -Developer's tips for documenting matplotlib -=========================================== +===================== +Writing documentation +===================== Getting started =============== @@ -10,81 +10,49 @@ Getting started 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 file -`doc-requirements.txt `_ -as well as listed below: +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 +:file:`doc-requirements.txt` and listed below: -1. Sphinx-1.3 or later(Version 1.5.0 is not supported) +1. Sphinx 1.3 or later (1.5.0 is not supported) 2. numpydoc 0.4 or later 3. IPython -4. Mock +4. mock 5. colorspacious -6. pillow -7. graphviz +6. Pillow +7. Graphviz .. note:: * You'll need a minimal working LaTeX distribution for many examples to run. - * `Graphviz `_ is not a python package, and needs - to be installed separately. + * `Graphviz `_ is not a Python package, + and needs to be installed separately. -General structure ------------------ - -All documentation is built from the :file:`doc/` directory. This directory contains both -``.rst`` files that contain pages in the documentation, directories that contain more -``.rst`` files, and configuration files for Sphinx_. - -.. note:: - - An exception to this are the directories :file:`gallery` and :file:`tutorials`, which - exist in the root directory. These contain Python files that are built by `Sphinx Gallery`_. - When the docs are built, directories of the same name will be generated inside of :file:`docs/`. - The generated directories :file:`docs/gallery` and :file:`docs/tutorials` can be safely deleted. - -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 users guide in html format, cd into -:file:`doc/` and do:: - - python make.py html - -or:: - - ./make.py html +General file structure +---------------------- -There are many other flags you can pass to ``make.py``, and you can see the -full list inside that file. Here are two useful ones: +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_. -* ``clean`` will delete the built Sphinx files. Use this command if you're getting strange - errors about missing paths or broken links, particularly if you move files around. -* ``latex`` builds a PDF of the documentation. - -In addition, these are useful flags: - -* ``--help`` will (among other things) display the allowed commands for ``make.py``. -* ``--allowsphinxwarnings`` will allow the docs to continue building even if Sphinx - throws a warning. This is useful for debugging and spot-checking many warnings - at once. - - -Organization of matplotlib's documentation -========================================== - -The actual ReStructured Text files are kept in :file:`doc/users`, +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 +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, we want to make navigating the Matplotlib documentation as easy as -possible. +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. @@ -93,290 +61,245 @@ statement, such as:: .. include:: ../../TODO -docstrings ----------- +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. -In addition to the "narrative" documentation described above, -matplotlib also defines its API reference documentation in docstrings. -For the most part, these are standard Python docstrings, but -matplotlib also includes some features to better support documenting -getters and setters. - -Matplotlib uses artist introspection of docstrings to support -properties. All properties that you want to support through ``setp`` -and ``getp`` should have a ``set_property`` and ``get_property`` -method in the :class:`~matplotlib.artist.Artist` class. Yes, this is -not ideal given python properties or enthought traits, but it is a -historical legacy for now. The setter methods use the docstring with -the ACCEPTS token to indicate the type of argument the method accepts. -e.g., in :class:`matplotlib.lines.Line2D`:: - - # in lines.py - def set_linestyle(self, linestyle): - """ - Set the linestyle of the line - - ACCEPTS: [ '-' | '--' | '-.' | ':' | 'steps' | 'None' | ' ' | '' ] - """ - -Since matplotlib uses a lot of pass-through ``kwargs``, e.g., in every -function that creates a line (:func:`~matplotlib.pyplot.plot`, -:func:`~matplotlib.pyplot.semilogx`, -:func:`~matplotlib.pyplot.semilogy`, etc...), it can be difficult for -the new user to know which ``kwargs`` are supported. Matplotlib uses -a docstring interpolation scheme to support documentation of every -function that takes a ``**kwargs``. The requirements are: - -1. single point of configuration so changes to the properties don't - require multiple docstring edits. - -2. as automated as possible so that as properties change, the docs - are updated automagically. - -The function :func:`matplotlib.artist.kwdoc` and the decorator -:func:`matplotlib.docstring.dedent_interpd` facilitate this. They combine -python string interpolation in the docstring with the matplotlib -artist introspection facility that underlies ``setp`` and ``getp``. -The ``kwdoc`` function gives the list of properties as a docstring. In order -to use this in another docstring, first update the -``matplotlib.docstring.interpd`` object, as seen in this example from -:mod:`matplotlib.lines`:: - - # in lines.py - docstring.interpd.update(Line2D=artist.kwdoc(Line2D)) +Building the docs +----------------- -Then in any function accepting :class:`~matplotlib.lines.Line2D` -pass-through ``kwargs``, e.g., :meth:`matplotlib.axes.Axes.plot`:: +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: - # in axes.py - @docstring.dedent_interpd - def plot(self, *args, **kwargs): - """ - Some stuff omitted +.. code-block:: sh - The kwargs are Line2D properties: - %(Line2D)s + python make.py html - kwargs scalex and scaley, if defined, are passed on - to autoscale_view to determine whether the x and y axes are - autoscaled; default True. See Axes.autoscale_view for more - information - """ - pass +The list of commands and flags for ``make.py`` can be listed by running +``python make.py --help``. In particular, -Note there is a problem for :class:`~matplotlib.artist.Artist` -``__init__`` methods, e.g., :meth:`matplotlib.patches.Patch.__init__`, -which supports ``Patch`` ``kwargs``, since the artist inspector cannot -work until the class is fully defined and we can't modify the -``Patch.__init__.__doc__`` docstring outside the class definition. -There are some some manual hacks in this case, violating the -"single entry point" requirement above -- see the -``docstring.interpd.update`` calls in :mod:`matplotlib.patches`. +* ``python make.py clean`` will delete the built Sphinx files. Use this command + if you're getting strange errors about missing paths or broken links, + particularly if you move files around. +* ``python make.py latex`` builds a PDF of the documentation. +* The ``--allowsphinxwarnings`` flag allows the docs to continue building even + if Sphinx throws a warning. This is useful for debugging and spot-checking + many warnings at once. .. _formatting-mpl-docs: -Formatting -========== - -The Sphinx website contains plenty of documentation_ concerning ReST markup and -working with Sphinx in general. Here are a few additional things to keep in mind: - -* Please familiarize yourself with the Sphinx directives for `inline - markup`_. Matplotlib's documentation makes heavy use of cross-referencing and - other semantic markup. For example, when referring to external files, use the - ``:file:`` directive. - -* Function arguments and keywords should be referred to using the *emphasis* - role. This will keep matplotlib's documentation consistent with Python's - documentation:: - - Here is a description of *argument* +Writing new documentation +========================= - Please do not use the `default role`:: +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. - Please do not describe `argument` like this. +An example docstring looks like: - nor the ``literal`` role:: +.. code-block:: python - Please do not describe ``argument`` like this. + def hlines(self, y, xmin, xmax, colors='k', linestyles='solid', + label='', **kwargs): + """ + Plot horizontal lines at each *y* from *xmin* to *xmax*. -* Sphinx does not support tables with column- or row-spanning cells for - latex output. Such tables can not be used when documenting matplotlib. + Parameters + ---------- + y : scalar or sequence of scalar + y-indexes where to plot the lines. -* Mathematical expressions can be rendered as png images in html, and in the - usual way by latex. For example: + xmin, xmax : scalar or 1D array_like + Respective beginning and end of each line. If scalars are + provided, all lines will have same length. - ``:math:`\sin(x_n^2)``` yields: :math:`\sin(x_n^2)`, and:: + colors : array_like of colors, optional, default: 'k' - .. math:: + linestyles : ['solid' | 'dashed' | 'dashdot' | 'dotted'], optional - \int_{-\infty}^{\infty}\frac{e^{i\phi}}{1+x^2\frac{e^{i\phi}}{1+x^2}} + label : string, optional, default: '' - yields: + Returns + ------- + lines : `~matplotlib.collections.LineCollection` - .. math:: + Other Parameters + ---------------- + **kwargs : `~matplotlib.collections.LineCollection` properties. - \int_{-\infty}^{\infty}\frac{e^{i\phi}}{1+x^2\frac{e^{i\phi}}{1+x^2}} + See also + -------- + vlines : vertical lines + axhline: horizontal line across the axes + """ -* Interactive IPython sessions can be illustrated in the documentation using - the following directive:: +The Sphinx website also contains plenty of documentation_ concerning ReST +markup and working with Sphinx in general. - .. sourcecode:: ipython +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: - In [69]: lines = plot([1,2,3]) +.. code-block:: python - which would yield: + `~matplotlib.collections.LineCollection` - .. sourcecode:: ipython +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):: - In [69]: lines = plot([1,2,3]) + python -m sphinx.ext.intersphinx 'https://docs.scipy.org/doc/numpy/objects.inv' -* Footnotes [#]_ can be added using ``[#]_``, followed later by:: - .. rubric:: Footnotes +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 - .. rubric:: Footnotes + Here is a description of *argument* - .. [#] For example. +Please do not use the ```default role```: -* Use the *note* and *warning* directives, sparingly, to draw attention to - important comments:: - .. note:: - Here is a note +.. code-block:: rst - yields: + Please do not describe `argument` like this. - .. note:: - here is a note +nor the ````literal```` role: - also: +.. code-block:: rst - .. warning:: - here is a warning + Please do not describe ``argument`` like this. -* Use the *deprecated* directive when appropriate:: +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`: - .. deprecated:: 0.98 - This feature is obsolete, use something else. +.. code-block:: python - yields: + # in lines.py + def set_linestyle(self, linestyle): + """ + Set the linestyle of the line - .. deprecated:: 0.98 - This feature is obsolete, use something else. + ACCEPTS: [ '-' | '--' | '-.' | ':' | 'steps' | 'None' | ' ' | '' ] + """ -* Use the *versionadded* and *versionchanged* directives, which have similar - syntax to the *deprecated* role:: - - .. versionadded:: 0.98 - The transforms have been completely revamped. - - .. versionadded:: 0.98 - The transforms have been completely revamped. - -* Use the *seealso* directive, for example:: - - .. seealso:: - - Using ReST :ref:`emacs-helpers`: - One example +Keyword arguments +----------------- +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 +supported. Matplotlib uses a docstring interpolation scheme to support +documentation of every function that takes a ``**kwargs``. The requirements +are: - A bit about :ref:`referring-to-mpl-docs`: - One more +1. single point of configuration so changes to the properties don't + require multiple docstring edits. - yields: +2. as automated as possible so that as properties change, the docs + are updated automatically. - .. seealso:: +The function `matplotlib.artist.kwdoc` and the decorator +`matplotlib.docstring.dedent_interpd` facilitate this. They combine Python +string interpolation in the docstring with the Matplotlib artist introspection +facility that underlies ``setp`` and ``getp``. The ``kwdoc`` function gives +the list of properties as a docstring. In order to use this in another +docstring, first update the ``matplotlib.docstring.interpd`` object, as seen in +this example from `matplotlib.lines`: - Using ResT :ref:`emacs-helpers`: - One example +.. code-block:: python - A bit about :ref:`referring-to-mpl-docs`: - One more + # in lines.py + docstring.interpd.update(Line2D=artist.kwdoc(Line2D)) -* Please keep the :ref:`glossary` in mind when writing documentation. You can - create a references to a term in the glossary with the ``:term:`` role. +Then in any function accepting `~.Line2D` pass-through ``kwargs``, e.g., +`matplotlib.axes.Axes.plot`: -* The autodoc extension will handle index entries for the API, but additional - entries in the index_ need to be explicitly added. +.. code-block:: python -* Please limit the text width of docstrings to 70 characters. + # in axes.py + @docstring.dedent_interpd + def plot(self, *args, **kwargs): + """ + Some stuff omitted -* Keyword arguments should be described using a definition list. + The kwargs are Line2D properties: + %(Line2D)s - .. note:: - matplotlib makes extensive use of keyword arguments as pass-through - arguments, there are a many cases where a table is used in place of a - definition list for autogenerated sections of docstrings. + kwargs scalex and scaley, if defined, are passed on + to autoscale_view to determine whether the x and y axes are + autoscaled; default True. See Axes.autoscale_view for more + information + """ -Figures -======= +Note there is a problem for `~matplotlib.artist.Artist` ``__init__`` methods, +e.g., `matplotlib.patches.Patch.__init__`, which supports ``Patch`` ``kwargs``, +since the artist inspector cannot work until the class is fully defined and +we can't modify the ``Patch.__init__.__doc__`` docstring outside the class +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`. -Dynamically generated figures ------------------------------ +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. -Figures can be automatically generated from scripts and included in -the docs. It is not necessary to explicitly save the figure in the -script, this will be done automatically at build time to ensure that -the code that is included runs and produces the advertised figure. +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.: -The path should be relative to the ``doc`` directory. Any plots -specific to the documentation should be added to the ``doc/mpl_examples/pyplots`` -directory and committed to git. Plots from the ``examples`` directory -may be referenced through the symlink ``mpl_examples`` in the ``doc`` -directory. e.g.:: +.. code-block:: rst - .. plot:: mpl_examples/pylab_examples/simple_plot.py + .. plot:: mpl_examples/lines_bars_and_markers/fill.py -The ``:scale:`` directive rescales the image to some percentage of the -original size, though we don't recommend using this in most cases -since it is probably better to choose the correct figure size and dpi -in mpl and let it handle the scaling. +Alternatively the plotting code can be placed directly in the docstring. +To include plots directly in docstrings, see the following guide: Plot directive documentation -'''''''''''''''''''''''''''' +---------------------------- .. automodule:: matplotlib.sphinxext.plot_directive - -Static figures --------------- - -Any figures that rely on optional system configurations need to be handled a -little differently. These figures are not to be generated during the -documentation build, in order to keep the prerequisites to the documentation -effort as low as possible. Please run the :file:`doc/pyplots/make.py` script -when adding such figures, and commit the script **and** the images to -git. Please also add a line to the README in doc/pyplots for any additional -requirements necessary to generate a new figure. Once these steps have been -taken, these figures can be included in the usual way:: - - .. plot:: mpl_examples/text_labels_and_annotations/tex_demo.py - :include-source: + :no-undoc-members: Examples -------- -The source of the files in the ``examples`` directory are -automatically included in the HTML docs. An image is generated and -included for all examples in the ``api`` and ``pylab_examples`` -directories. To exclude the example from having an image rendered, -insert the following special comment anywhere in the script:: - - # -*- noplot -*- +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. -Animations ----------- +Adding animations +================= -We have a matplotlib google/gmail account with username ``mplgithub`` +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 +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 +uploading to `matplotlib's Youtube channel `_ and inserting the -embedding string youtube provides like:: +embedding string youtube provides like: + +.. code-block:: rst .. raw:: html @@ -387,7 +310,7 @@ embedding string youtube provides like:: An example save command to generate a movie looks like this -.. sourcecode:: python +.. code-block:: python ani = animation.FuncAnimation(fig, animate, np.arange(1, len(y)), interval=25, blit=True, init_func=init) @@ -399,44 +322,41 @@ google docs to the mplgithub account. .. _referring-to-mpl-docs: -Referring to mpl documents -========================== +Referring to data files +======================= -In the documentation, you may want to include to a document in the -matplotlib src, e.g., a license file or an image file from `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`, we refer to the -image icons with:: +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:: .. image:: ../../lib/matplotlib/mpl-data/images/subplots.png -In the `users` subdirectory, if I want to refer to a file in the mpl-data -directory, I use the symlink directory. For example, from -`customizing.rst`:: +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`:: .. literalinclude:: ../../lib/matplotlib/mpl-data/matplotlibrc -One exception to this is when referring to the examples dir. Relative -paths are extremely confusing in the sphinx plot extensions, so -without getting into the dirty details, 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 +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. -In the top level doc directory we have symlinks pointing to -the mpl `examples`:: +In the top level :file:`doc` directory we have symlinks pointing to the +Matplotlib :file:`examples`: + +.. code-block:: sh home:~/mpl/doc> ls -l mpl_* mpl_examples -> ../examples -So we can include plots from the examples dir using the symlink:: - - .. plot:: mpl_examples/pylab_examples/simple_plot.py +So we can include plots from the examples dir using the symlink: +.. code-block:: rst -We used to use a symlink for :file:`mpl-data` too, but the distro -becomes very large on platforms that do not support links (e.g., the font -files are duplicated and large) + .. plot:: mpl_examples/pylab_examples/simple_plot.py .. _internal-section-refs: @@ -444,42 +364,48 @@ Internal section references =========================== To maximize internal consistency in section labeling and references, -use hyphen separated, descriptive labels for section references, e.g.,:: +use hyphen separated, descriptive labels for section references, e.g.: + +.. code-block:: rst .. _howto-webapp: -and refer to it using the standard reference syntax:: +and refer to it using the standard reference syntax: + +.. code-block:: rst See :ref:`howto-webapp` Keep in mind that we may want to reorganize the contents later, so -let's avoid top level names in references like ``user`` or ``devel`` +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:: +backend?" could later become part of the users guide, so the label: + +.. code-block:: rst .. _what-is-a-backend -is better than:: +is better than: + +.. code-block:: rst .. _faq-backend -In addition, since underscores are widely used by Sphinx itself, let's prefer +In addition, since underscores are widely used by Sphinx itself, please use hyphens to separate words. - - -Section names, etc -================== +Section name formatting +======================= 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, you provide the +``inheritance-diagram`` directive. To use it, provide the directive with a number of class or module names (separated by whitespace). If a module name is provided, all classes in that module will be used. All of the ancestors of these classes will be included @@ -491,7 +417,9 @@ class ``matplotlib.patches.Patch`` is shown as ``Patch``. If *parts* == 2, it is shown as ``patches.Patch``. If *parts* == 0, the full path is shown. -Example:: +Example: + +.. code-block:: rst .. inheritance-diagram:: matplotlib.patches matplotlib.lines matplotlib.text :parts: 2 @@ -499,7 +427,6 @@ Example:: .. inheritance-diagram:: matplotlib.patches matplotlib.lines matplotlib.text :parts: 2 - .. _emacs-helpers: Emacs helpers @@ -509,7 +436,9 @@ There is an emacs mode `rst.el `_ which automates many important ReST tasks like building and updating table-of-contents, and promoting or demoting section headings. Here -is the basic ``.emacs`` configuration:: +is the basic ``.emacs`` configuration: + +.. code-block:: lisp (require 'rst) (setq auto-mode-alist @@ -517,7 +446,6 @@ is the basic ``.emacs`` configuration:: ("\\.rst$" . rst-mode) ("\\.rest$" . rst-mode)) auto-mode-alist)) - Some helpful functions:: C-c TAB - rst-toc-insert