Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Three more plot_directive configuration options #1042

Merged
merged 3 commits into from

2 participants

@abakan

Hello,

I have added three new configuration options to Sphinx extension plot_directive. The added code must not change any behaviour of the extension, but will add more flexibility.

  • plot_apply_rcparams : allows appyling rcParams when context is used
  • plot_working_directory : allows running plot directive codes in any directory
  • plot_template : allows customization of template used for generating restructured text

This is how I use these new options to customize plot_directive when documenting a project of mine.

plot_formats = [('png', 80), ('pdf', 80)]
plot_pre_code = """import numpy as np
from prody import *
from matplotlib import pyplot as plt
"""
plot_working_directory = os.path.join(os.getcwd(), 'doctest')
plot_template = """
{{ source_code }}

{{ only_html }}


   {% for img in images %}
   .. figure:: {{ build_dir }}/{{ img.basename }}.png
      {%- for option in options %}
      {{ option }}
      {% endfor %}

      {{ caption }}
   {% endfor %}

{{ only_latex }}

   {% for img in images %}
   .. image:: {{ build_dir }}/{{ img.basename }}.pdf
   {% endfor %}

"""
plot_rcparams = {'font.size': 10,
                 'xtick.labelsize': 'small',
                 'ytick.labelsize': 'small',
                 'figure.figsize': [5., 4.],}
plot_apply_rcparams = True
@abakan abakan Added more configuration options.
* plot_apply_rcparams
Allows appyling rcParams when context is used.
* plot_working_directory
Allows running plot directive codes in any directory.
* plot_template
Allows customization of template used for generating restructured text.
d30d57c
@WeatherGod WeatherGod commented on the diff
lib/matplotlib/sphinxext/plot_directive.py
@@ -284,6 +299,9 @@ def setup(app):
app.add_config_value('plot_basedir', None, 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)
+ app.add_config_value('plot_working_directory', None, True)
@WeatherGod Collaborator

Shouldn't this be defaulting to False, rather than None? Booleans are much more clear in their intent than Nones.

@WeatherGod Collaborator

Sorry, got confused. I see that it is supposed to be a string

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/matplotlib/sphinxext/plot_directive.py
@@ -445,7 +463,9 @@ def run_code(code, code_path, ns=None, function_name=None):
pwd = os.getcwd()
old_sys_path = list(sys.path)
- if code_path is not None:
+ if setup.config.plot_working_directory:
@WeatherGod Collaborator

Therefore, this line should be

if setup.config.plot_working_directory is not None:
@WeatherGod Collaborator

Also, note how we insert "dirname" to the path. What is the reasoning for not including plot_working_directory into the path (or dirname)?

@abakan
abakan added a note

I have made suggested changes, and updated the doc string to note that working directory is also added to sys.path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/matplotlib/sphinxext/plot_directive.py
@@ -105,6 +105,21 @@
A dictionary containing any non-standard rcParams that should
be applied before each plot.
+ plot_apply_rcparams
+ Apply rcParams before each plot. When context is used, rcParams are
+ not applied, and this configuration option overrides this behavior.
+
+ plot_working_directory
+ By default, the working directory will be changed to the directory of
+ the example, so the code can get at its data files, if any. Also its
+ path to sys.path so it can import any helper modules sitting beside it.
@WeatherGod Collaborator

"Also its path to sys.path..." <---- there is a verb missing here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/matplotlib/sphinxext/plot_directive.py
@@ -105,6 +105,21 @@
A dictionary containing any non-standard rcParams that should
be applied before each plot.
+ plot_apply_rcparams
+ Apply rcParams before each plot. When context is used, rcParams are
@WeatherGod Collaborator

Should mention what the default behavior is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@WeatherGod
Collaborator

Besides the points I made, I have no problem with this PR. If anything, the doc strings could be a little bit more descriptive to help illustrate the possibilities, but they are largely sufficient at this point. Let me know when you address my comments.

@abakan

Thanks for your comments. I have addressed all of them.

I have a question about handling potential problems with the configuration option plot_working_directory. If user sets an invalid path, an OSError is raised and Sphinx terminates. If I catch this exception and throw a PlotError instead, Sphinx keeps evaluating plot directives, but the working directory is not changed and when needed data files are not accessed, causing other problems.

I would favor throwing OSError with a message saying that "plot_working_directory is not a valid path", which may be helpful for troubleshooting.

How do you think this should be handled? Thanks again for your prompt attention.

@WeatherGod
Collaborator

Good question. I agree with the latter approach.

@abakan abakan Handling potential plot_working_directory errors
Handling potential invalid directory path and invalid type errors.
72a8ec4
@abakan

I am handling potential OSError and TypeError in the updated module. Sphinx output for different exception types are below. Any other suggestions? Thank you.

Invalid path type:

Exception occurred:
  File "/home/abakan/Code/ProDy/prody/plot_directive.py", line 476, in run_code
    raise TypeError(str(err) + '\n`plot_working_directory` option in '
TypeError: coercing to Unicode: need string or buffer, int found
`plot_working_directory` option in Sphinx configuration file must be a string or None
The full traceback has been saved in /tmp/sphinx-err-7DZjB6.log, if you want to report the issue to the developers.
Please also report this if it was a user error, so that a better error message can be provided next time.
Either send bugs to the mailing list at <http://groups.google.com/group/sphinx-dev/>,
or report them in the tracker at <http://bitbucket.org/birkenfeld/sphinx/issues/>. Thanks!
make: *** [html] Error 1

Invalid type path:

Exception occurred:
  File "/home/abakan/Code/ProDy/prody/plot_directive.py", line 472, in run_code
    raise OSError(str(err) + '\n`plot_working_directory` option in'
OSError: [Errno 2] No such file or directory: '/home/abakan/Code/ProDy/doc/doctests'
`plot_working_directory` option inSphinx configuration file must be a valid directory path
The full traceback has been saved in /tmp/sphinx-err-OBTBwg.log, if you want to report the issue to the developers.
Please also report this if it was a user error, so that a better error message can be provided next time.
Either send bugs to the mailing list at <http://groups.google.com/group/sphinx-dev/>,
or report them in the tracker at <http://bitbucket.org/birkenfeld/sphinx/issues/>. Thanks!
make: *** [html] Error 1
@WeatherGod
Collaborator

Looks good to me. Thanks for your work. Merging...

@WeatherGod WeatherGod merged commit 09e7dd2 into matplotlib:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 27, 2012
  1. @abakan

    Added more configuration options.

    abakan authored
    * plot_apply_rcparams
    Allows appyling rcParams when context is used.
    * plot_working_directory
    Allows running plot directive codes in any directory.
    * plot_template
    Allows customization of template used for generating restructured text.
  2. @abakan
  3. @abakan

    Handling potential plot_working_directory errors

    abakan authored
    Handling potential invalid directory path and invalid type errors.
This page is out of date. Refresh to see the latest.
Showing with 36 additions and 4 deletions.
  1. +36 −4 lib/matplotlib/sphinxext/plot_directive.py
View
40 lib/matplotlib/sphinxext/plot_directive.py
@@ -105,6 +105,23 @@
A dictionary containing any non-standard rcParams that should
be applied before each plot.
+ plot_apply_rcparams
+ By default, rcParams are applied when `context` option is not used in
+ a plot directive. This configuration option overrides this behaviour
+ and applies rcParams before each plot.
+
+ plot_working_directory
+ By default, the working directory will be changed to the directory of
+ the example, so the code can get at its data files, if any. Also its
+ path will be added to `sys.path` so it can import any helper modules
+ sitting beside it. This configuration option can be used to specify
+ a central directory (also added to `sys.path`) where data files and
+ helper modules for all code are located.
+
+ plot_template
+ Provide a customized template for preparing resturctured text.
+
+
"""
from __future__ import print_function
@@ -284,6 +301,9 @@ def setup(app):
app.add_config_value('plot_basedir', None, 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)
+ app.add_config_value('plot_working_directory', None, True)
@WeatherGod Collaborator

Shouldn't this be defaulting to False, rather than None? Booleans are much more clear in their intent than Nones.

@WeatherGod Collaborator

Sorry, got confused. I see that it is supposed to be a string

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ app.add_config_value('plot_template', None, True)
app.connect('doctree-read', mark_plot_labels)
@@ -445,7 +465,19 @@ def run_code(code, code_path, ns=None, function_name=None):
pwd = os.getcwd()
old_sys_path = list(sys.path)
- if code_path is not None:
+ if setup.config.plot_working_directory is not None:
+ try:
+ os.chdir(setup.config.plot_working_directory)
+ except OSError as err:
+ raise OSError(str(err) + '\n`plot_working_directory` option in'
+ 'Sphinx configuration file must be a valid '
+ 'directory path')
+ except TypeError as err:
+ raise TypeError(str(err) + '\n`plot_working_directory` option in '
+ 'Sphinx configuration file must be a string or '
+ 'None')
+ sys.path.insert(0, setup.config.plot_working_directory)
+ elif code_path is not None:
dirname = os.path.abspath(os.path.dirname(code_path))
os.chdir(dirname)
sys.path.insert(0, dirname)
@@ -564,7 +596,7 @@ def render_figures(code, code_path, output_dir, output_base, context,
ns = {}
for i, code_piece in enumerate(code_pieces):
- if not context:
+ if not context or config.plot_apply_rcparams:
clear_state(config.plot_rcparams)
run_code(code_piece, code_path, ns, function_name)
@@ -588,7 +620,7 @@ def render_figures(code, code_path, output_dir, output_base, context,
results.append((code_piece, images))
- if not context:
+ if not context or config.plot_apply_rcparams:
clear_state(config.plot_rcparams)
return results
@@ -733,7 +765,7 @@ def run(arguments, content, options, state_machine, state, lineno):
src_link = None
result = format_template(
- TEMPLATE,
+ config.plot_template or TEMPLATE,
dest_dir=dest_dir_link,
build_dir=build_dir_link,
source_link=src_link,
Something went wrong with that request. Please try again.