Skip to content

sphinx plot directive: sources relative to rst file #12456

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

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
27 changes: 27 additions & 0 deletions doc/api/next_api_changes/2018-10-09-plot-directive.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Changes regarding the Sphinx plot directive
```````````````````````````````````````````

Fixed a bug in the Sphinx plot directive (.. plot:: path/to/plot_script.py)
where the source Python file was not being found relative to the directory of
the file containing the directive. In addition, its behavior was changed to
make it more streamlined with other Sphinx commands.

Documents that were using this feature may need to adjust the path argument
given to the plot directive. Two options are available:

1. Use absolute paths to find the file relative the ``plot_basedir`` (which
defaults to the source directory, where conf.py is).
2. Use relative paths and the file is found relative to the directory of the
file containing the directive.

Before this change, relative paths were resolved relative to ``plot_basedir``
(which defaulted to the source directory) and absolute paths were pointing to
files in the host system.

Since this will break documentations that were depending on the old behavior,
there is a deprecation period and a new configuration option is introduced to
get the old behavior. To get the old behavior specify
``plot_path_resolution_method='old'`` in ``conf.py`` and specify
``plot_path_resolution_method='relative'`` to get the new behavior. The old
behavior will be removed in future. The users are advised to switch to the new
behavior and fix the plot directives accordingly.
1 change: 1 addition & 0 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ def _check_dependencies():
# ----------------------------

plot_formats = [('png', 100), ('pdf', 100)]
plot_path_resolution_method = 'relative'

# Github extension

Expand Down
4 changes: 2 additions & 2 deletions doc/devel/documenting_mpl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ so plots from the examples directory can be included using

.. code-block:: rst

.. plot:: gallery/lines_bars_and_markers/simple_plot.py
.. plot:: /gallery/lines_bars_and_markers/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 correct reference
Expand Down Expand Up @@ -669,7 +669,7 @@ the file :file:`examples/text_labels_and_annotations/legend.py`:
Examples
--------

.. plot:: gallery/text_labels_and_annotations/legend.py
.. plot:: /gallery/text_labels_and_annotations/legend.py
"""

Note that ``examples/text_labels_and_annotations/legend.py`` has been mapped to
Expand Down
6 changes: 3 additions & 3 deletions lib/matplotlib/axes/_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ def legend(self, *args, **kwargs):
Examples
--------

.. plot:: gallery/text_labels_and_annotations/legend.py
.. plot:: /gallery/text_labels_and_annotations/legend.py

"""
handles, labels, extra_args, kwargs = mlegend._parse_legend_args(
Expand Down Expand Up @@ -1272,7 +1272,7 @@ def eventplot(self, positions, orientation='horizontal', lineoffsets=1,
Examples
--------

.. plot:: gallery/lines_bars_and_markers/eventplot_demo.py
.. plot:: /gallery/lines_bars_and_markers/eventplot_demo.py
"""
self._process_unit_info(xdata=positions,
ydata=[lineoffsets, linelengths],
Expand Down Expand Up @@ -3879,7 +3879,7 @@ def bxp(self, bxpstats, positions=None, widths=None, vert=True,
Examples
--------

.. plot:: gallery/statistics/bxp.py
.. plot:: /gallery/statistics/bxp.py

"""
# lists of artists to be output
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -1468,7 +1468,7 @@ def __init__(self,
Examples
--------

.. plot:: gallery/lines_bars_and_markers/eventcollection_demo.py
.. plot:: /gallery/lines_bars_and_markers/eventcollection_demo.py
"""

segment = (lineoffset + linelength / 2.,
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/path.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ def make_compound_path_from_polys(cls, XY):
numsides x 2) numpy array of vertices. Return object is a
:class:`Path`

.. plot:: gallery/misc/histogram_path.py
.. plot:: /gallery/misc/histogram_path.py

"""

Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/sankey.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def __init__(self, ax=None, scale=1.0, unit='', format='%G', gap=0.25,

**Examples:**

.. plot:: gallery/specialty_plots/sankey_basics.py
.. plot:: /gallery/specialty_plots/sankey_basics.py
"""
# Check the arguments.
if gap < 0:
Expand Down
62 changes: 54 additions & 8 deletions lib/matplotlib/sphinxext/plot_directive.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@

.. plot:: path/to/plot.py plot_function1

Relative paths are found relative to the directory of the file containing
the directive. Absolute paths (paths starting with ``/``) are found
relative to ``plot_basedir`` (see Configuration options).

2. Included as **inline content** to the directive::

.. plot::
Expand Down Expand Up @@ -96,10 +100,26 @@
import numpy as np
from matplotlib import pyplot as plt

plot_path_resolution_method
The method to use for resolving file names that come after the
``plot::`` directive. Two options are available: ``relative`` and
``old``. Defaults to ``old`` but the default value will
change to ``relative`` in future versions. The ``old`` method
is deprecated and will be removed in future. See the ``plot_basedir``
for explanation of methods.

plot_basedir
Base directory, to which ``plot::`` file names are relative
to. (If None or empty, file names are relative to the
directory where the file containing the directive is.)
Base directory, to which ``plot::`` file names are relative.
Defaults to the source directory.

If ``plot_path_resolution_method`` is ``relative``, relative file names
are found relative to the directory of the file containing the
directive. Absolute file names (paths starting with ``/``) are found
relative to ``plot_basedir``.

If ``plot_path_resolution_method`` is ``old``, relative paths are found
relative to ``plot_basedir`` and absolute paths point to files in the
host system. This method is deprecated and will be removed in future.

plot_formats
File formats to generate. List of tuples or strings::
Expand Down Expand Up @@ -283,6 +303,7 @@ def setup(app):
app.add_config_value('plot_html_show_source_link', True, True)
app.add_config_value('plot_formats', ['png', 'hires.png', 'pdf'], True)
app.add_config_value('plot_basedir', None, True)
app.add_config_value('plot_path_resolution_method', 'old', True)
app.add_config_value('plot_html_show_formats', True, True)
app.add_config_value('plot_rcparams', {}, True)
app.add_config_value('plot_apply_rcparams', False, True)
Expand Down Expand Up @@ -665,12 +686,37 @@ def run(arguments, content, options, state_machine, state, lineno):
rst_dir = os.path.dirname(rst_file)

if len(arguments):
if not config.plot_basedir:
source_file_name = os.path.join(setup.app.builder.srcdir,
directives.uri(arguments[0]))

# if the new method is selected for resolving paths
if config.plot_path_resolution_method.lower() == 'relative':

if arguments[0].startswith('/'):
arguments[0] = arguments[0][1:]
src_dir = config.plot_basedir or setup.app.builder.srcdir
else:
src_dir = rst_dir

source_file_name = os.path.join(src_dir, directives.uri(arguments[0]))

else:
source_file_name = os.path.join(setup.confdir, config.plot_basedir,
directives.uri(arguments[0]))

cbook.warn_deprecated(
'3.2', message='You are using an old method '
'to resolve filenames of the ``.. ::plot`` directive. Please '
'switch to the new method by specifying '
'``plot_path_resolution_method=\'relative\'`` in your conf.py '
'and fix the filenames accordingly. Please see '
'matplotlib/doc/api/next_api_changes/2018-10-09-plot-directive.rst '
'for more information. The old method will be removed in '
'%(removal)s.', removal='4.0')

if not config.plot_basedir:
source_file_name = os.path.join(
setup.app.builder.srcdir, directives.uri(arguments[0]))

else:
source_file_name = os.path.join(
setup.confdir, config.plot_basedir, directives.uri(arguments[0]))

# If there is content, it will be passed as a caption.
caption = '\n'.join(content)
Expand Down
12 changes: 6 additions & 6 deletions lib/mpl_toolkits/mplot3d/axes3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -1959,8 +1959,8 @@ def plot_trisurf(self, *args, color=None, norm=None, vmin=None, vmax=None,
Examples
--------

.. plot:: gallery/mplot3d/trisurf3d.py
.. plot:: gallery/mplot3d/trisurf3d_2.py
.. plot:: /gallery/mplot3d/trisurf3d.py
.. plot:: /gallery/mplot3d/trisurf3d_2.py

.. versionadded:: 1.2.0
This plotting function was added for the v1.2.0 release.
Expand Down Expand Up @@ -2802,10 +2802,10 @@ def voxels(self, *args, facecolors=None, edgecolors=None, shade=True,

Examples
--------
.. plot:: gallery/mplot3d/voxels.py
.. plot:: gallery/mplot3d/voxels_rgb.py
.. plot:: gallery/mplot3d/voxels_torus.py
.. plot:: gallery/mplot3d/voxels_numpy_logo.py
.. plot:: /gallery/mplot3d/voxels.py
.. plot:: /gallery/mplot3d/voxels_rgb.py
.. plot:: /gallery/mplot3d/voxels_torus.py
.. plot:: /gallery/mplot3d/voxels_numpy_logo.py
"""

# work out which signature we should be using, and use it to parse
Expand Down