diff --git a/doc/api/next_api_changes/2018-10-09-plot-directive.rst b/doc/api/next_api_changes/2018-10-09-plot-directive.rst new file mode 100644 index 000000000000..277475e15154 --- /dev/null +++ b/doc/api/next_api_changes/2018-10-09-plot-directive.rst @@ -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. diff --git a/doc/conf.py b/doc/conf.py index df7a93b31cdc..a17040bf1fea 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -204,6 +204,7 @@ def _check_dependencies(): # ---------------------------- plot_formats = [('png', 100), ('pdf', 100)] +plot_path_resolution_method = 'relative' # Github extension diff --git a/doc/devel/documenting_mpl.rst b/doc/devel/documenting_mpl.rst index 473e5aa2f7e5..8623f5f9743f 100644 --- a/doc/devel/documenting_mpl.rst +++ b/doc/devel/documenting_mpl.rst @@ -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 @@ -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 diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index affc329f1be0..8b08e6d620ee 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -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( @@ -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], @@ -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 diff --git a/lib/matplotlib/collections.py b/lib/matplotlib/collections.py index 53df43a41a45..25325b523877 100644 --- a/lib/matplotlib/collections.py +++ b/lib/matplotlib/collections.py @@ -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., diff --git a/lib/matplotlib/path.py b/lib/matplotlib/path.py index 16b88da093ee..c422cb8f0aaa 100644 --- a/lib/matplotlib/path.py +++ b/lib/matplotlib/path.py @@ -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 """ diff --git a/lib/matplotlib/sankey.py b/lib/matplotlib/sankey.py index c93f07037ac0..b29d44e6e0df 100644 --- a/lib/matplotlib/sankey.py +++ b/lib/matplotlib/sankey.py @@ -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: diff --git a/lib/matplotlib/sphinxext/plot_directive.py b/lib/matplotlib/sphinxext/plot_directive.py index 1ab5aa5e17dd..c08dd88e98b0 100644 --- a/lib/matplotlib/sphinxext/plot_directive.py +++ b/lib/matplotlib/sphinxext/plot_directive.py @@ -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:: @@ -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:: @@ -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) @@ -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) diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index ccf658bbc72d..429b7a4c8b16 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -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. @@ -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