Skip to content
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

allow selecting the backend by setting the environment variable MPLBACKEND #3710

Merged
merged 6 commits into from Nov 18, 2014
Merged
3 changes: 3 additions & 0 deletions CHANGELOG
@@ -1,3 +1,6 @@
2014-10-27 Allowed selection of the backend using the `MPLBACKEND` environment
variable. Added documentation on backend selection methods.

2014-09-27 Overhauled `colors.LightSource`. Added `LightSource.hillshade` to
allow the independent generation of illumination maps. Added new
types of blending for creating more visually appealing shaded relief
Expand Down
15 changes: 10 additions & 5 deletions doc/devel/coding_guide.rst
Expand Up @@ -270,15 +270,20 @@ external backend via the ``module`` directive. if

backend : module://my_backend

* with the use directive is your script::

import matplotlib
matplotlib.use('module://my_backend')
* with the :envvar:`MPLBACKEND` environment variable::

> export MPLBACKEND="module://my_backend"
> python simple_plot.py

* from the command shell with the -d flag::
* from the command shell with the `-d` flag::

> python simple_plot.py -d module://my_backend
> python simple_plot.py -dmodule://my_backend
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you put the space back in there? These docs are for reading, not typing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the code, now I wonder if it ever worked with the space in there...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@WeatherGod At least it does not work with module-backends, because the argument without the first two characters is passed to use() and use() contains arg.startswith('module://') without a previous .strip() call.


* with the use directive is your script::
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is -> in


import matplotlib
matplotlib.use('module://my_backend')

.. _sample-data:

Expand Down
6 changes: 6 additions & 0 deletions doc/faq/environment_variables_faq.rst
Expand Up @@ -30,6 +30,12 @@ Environment Variables
used to find a base directory in which the :file:`matplotlib`
subdirectory is created.

.. envvar:: MPLBACKEND

This optional variable can be set to choose the matplotlib backend. Using the
`-d` command line parameter or the :func:`~matplotlib.use` function will
override this value. See :ref:`what-is-a-backend`.

.. _setting-linux-osx-environment-variables:

Setting environment variables in Linux and OS-X
Expand Down
53 changes: 42 additions & 11 deletions doc/faq/usage_faq.rst
Expand Up @@ -302,19 +302,50 @@ pygtk, wxpython, tkinter, qt4, or macosx; also referred to as
"interactive backends") and hardcopy backends to make image files
(PNG, SVG, PDF, PS; also referred to as "non-interactive backends").

There are a two primary ways to configure your backend. One is to set
the ``backend`` parameter in your ``matplotlibrc`` file (see
:ref:`customizing-matplotlib`)::
There are a four ways to configure your backend, in reversed order
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"reversed order of precedence" when I think of "reversed order", I am usually thinking of things decreasing. This could be reworded better.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@WeatherGod How about this:

There are a four ways to configure your backend. If they conflict each other,
the method mentioned last in the following list will be used, e.g. calling
:func:`~matplotlib.use()` will override the settings in your ``matplotlibrc``.

of precedence:

backend : WXAgg # use wxpython with antigrain (agg) rendering
#. The ``backend`` parameter in your ``matplotlibrc`` file (see
:ref:`customizing-matplotlib`)::

The other is to use the matplotlib :func:`~matplotlib.use` directive::
backend : WXAgg # use wxpython with antigrain (agg) rendering

import matplotlib
matplotlib.use('PS') # generate postscript output by default
#. Setting the :envvar:`MPLBACKEND` environment
variable, either for your current shell or for a single script::

If you use the ``use`` directive, this must be done before importing
:mod:`matplotlib.pyplot` or :mod:`matplotlib.pylab`.
> export MPLBACKEND="module://my_backend"
> python simple_plot.py

> MPLBACKEND="module://my_backend" python simple_plot.py

Setting this environment variable will override the ``backend`` parameter
in *any* ``matplotlibrc``, even if there is a ``matplotlibrc`` in your
current working directory. Therefore setting :envvar:`MPLBACKEND`
globally, e.g. in your ``.bashrc`` or ``.profile``, is discouraged as it
might lead to counter-intuitive behavior.

#. To set the backend for a single script, you can alternatively use the `-d`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am ambivalent about advertising this feature. I do see the warning below, but I'd much rather go the route of deprecating this feature in favor of the environment variable.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah -- maybe we should start the deprecation process for this now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like the idea of completely leaving -d out of the documentation as long as it still works. How about replacing the previous warning about issue 1986 with the following:

This method is **deprecated** as the `-d` argument might conflict with
scripts which parse command line arguments (see issue
`#1986 <https://github.com/matplotlib/matplotlib/issues/1986>`_). You
should use :envvar:`MPLBACKEND` instead.

Should using the -d flag also cause a runtime warning?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes please

On Tue, Nov 18, 2014 at 11:29 AM, Florian Rhiem notifications@github.com
wrote:

In doc/faq/usage_faq.rst:

-If you use the use directive, this must be done before importing
-:mod:matplotlib.pyplot or :mod:matplotlib.pylab.

  •    > export MPLBACKEND="module://my_backend"
    
  •    > python simple_plot.py
    
  •    > MPLBACKEND="module://my_backend" python simple_plot.py
    
  • Setting this environment variable will override the backend parameter
  • in any matplotlibrc, even if there is a matplotlibrc in your
  • current working directory. Therefore setting :envvar:MPLBACKEND
  • globally, e.g. in your .bashrc or .profile, is discouraged as it
  • might lead to counter-intuitive behavior.

+#. To set the backend for a single script, you can alternatively use the -d

I don't like the idea of completely leaving -d out of the documentation
as long as it is still supported. How about replacing the previous warning
about issue 1986 #1986
with the following:

This method is deprecated as the -d argument might conflict with
scripts which parse command line arguments (see issue
#1986 <https://github.com/matplotlib/matplotlib/issues/1986>_). You
should use :envvar:MPLBACKEND instead.

Should using the -d flag also cause a runtime warning?


Reply to this email directly or view it on GitHub
https://github.com/matplotlib/matplotlib/pull/3710/files#r20517466.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should probably raise a mplDeprecation warning. Like #3812

command line argument::

> python script.py -dbackend
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space


This might conflict with scripts which parse
command line arguments (see issue
`#1986 <https://github.com/matplotlib/matplotlib/issues/1986>`_), so you
should use :envvar:`MPLBACKEND` instead.

#. If your script depends on a specific backend you can use the
:func:`~matplotlib.use` function::

import matplotlib
matplotlib.use('PS') # generate postscript output by default

If you use the ``use``, this must be done before importing
:mod:`matplotlib.pyplot`, calling :func:`~matplotlib.use` after pyplot
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comma to period, and "calling" --> "Calling"

has been imported will have no effect. Using `use` will
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

double backticks? or should it be single backticks earlier in this paragraph?

require changes in your code if users want to use a different
backend. Therefore, you should avoid explicitly calling ``use`` unless
absolutely necessary.

.. note::
Backend name specifications are not case-sensitive; e.g., 'GTKAgg'
Expand All @@ -324,8 +355,8 @@ With a typical installation of matplotlib, such as from a
binary installer or a linux distribution package, a good default
backend will already be set, allowing both interactive work and
plotting from scripts, with output to the screen and/or to
a file, so at least initially you will not need to use either of the
two methods given above.
a file, so at least initially you will not need to use any of the
methods given above.

If, however, you want to write graphical user interfaces, or a web
application server (:ref:`howto-webapp`), or need a better
Expand Down
7 changes: 7 additions & 0 deletions doc/users/whats_new.rst
Expand Up @@ -60,6 +60,13 @@ Added a :code:`pivot` kwarg to :func:`~mpl_toolkits.mplot3d.Axes3D.quiver`
that controls the pivot point around which the quiver line rotates. This also
determines the placement of the arrow head along the quiver line.

New backend selection
---------------------

The environment variable :envvar:`MPLBACKEND` can now be used to set the
matplotlib backend.


.. _whats-new-1-4:

new in matplotlib-1.4
Expand Down
8 changes: 8 additions & 0 deletions lib/matplotlib/__init__.py
Expand Up @@ -1373,9 +1373,17 @@ def tk_window_focus():
if s.startswith(str('-d')) and len(s) > 2: # look for a -d flag
try:
use(s[2:])
break
except (KeyError, ValueError):
pass
# we don't want to assume all -d flags are backends, e.g., -debug
else:
# no backend selected from the command line, so we check the environment
# variable MPLBACKEND
try:
use(os.environ['MPLBACKEND'])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mdboom, just as a sanity check, are we going to have to worry at all about string/unicode issues here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so. It was environment variables that contain Unicode paths that were giving us grief. In this case both the key and value should be ascii. (It's possible that someone might use unicode in the "module://my_custom_backend" form, but doing that on Python 2 would be insane/impossible for so many other reasons, it's not worth worrying about).

except (KeyError, ValueError):
pass

default_test_modules = [
'matplotlib.tests.test_agg',
Expand Down