Warning After Upgrade to -0.91.2

I just upgraded my Slackware-11.0 workstation from matplotlib-0.90.1 to
-0.91.2. When I now start my application I see this:

/usr/lib/python2.4/site-packages/matplotlib/__init__.py:753: UserWarning:
This call to matplotlib.use() has no effect
because the the backend has already been chosen;
matplotlib.use() must be called *before* pylab, matplotlib.pyplot,
or matplotlib.backends is imported for the first time.

   warnings.warn(_use_error_msg)

   I don't know to which matplotlib.use() call the message refers. At the top
of the module in which matplotlib is used I have
                            matplotlib.use('WXAgg')

and the above warning did not appear with the prior version of the library.

   Please help me to understand what changed, and how to fix the change so
the warning no longer appears.

Thanks,

Rich

···

--
Richard B. Shepard, Ph.D. | Integrity Credibility
Applied Ecosystem Services, Inc. | Innovation
<http://www.appl-ecosys.com> Voice: 503-667-4517 Fax: 503-667-8863

Rich Shepard wrote:

   I just upgraded my Slackware-11.0 workstation from matplotlib-0.90.1 to
-0.91.2. When I now start my application I see this:

/usr/lib/python2.4/site-packages/matplotlib/__init__.py:753: UserWarning:
This call to matplotlib.use() has no effect
because the the backend has already been chosen;
matplotlib.use() must be called *before* pylab, matplotlib.pyplot,
or matplotlib.backends is imported for the first time.

   warnings.warn(_use_error_msg)

   I don't know to which matplotlib.use() call the message refers. At the top
of the module in which matplotlib is used I have
                            matplotlib.use('WXAgg')

and the above warning did not appear with the prior version of the library.

   Please help me to understand what changed, and how to fix the change so
the warning no longer appears.

What changed is that I added a warning where previously there was only a silent error--the matplotlib.use command was being ignored. Sometimes this (ignoring the command) is harmless, but it is never the user's intent and in some cases it can cause puzzling problems. It often occurs when a script or module does "from pylab import *" or "import pylab as P", and then later "import matplotlib; matplotlib.use('Agg')". In this example, the user intends to make plots non-interactively, writing them to files, but the whole gui machinery for the default backend (e.g., gtkagg or wxagg or tkagg) is imported unintentionally.

One way to find out where the warning is coming from is to invoke your script as

python -Werror myscript.py

which will turn the warning into an error and thereby trigger an exception traceback.

What this will *not* tell you is where the *earlier* call to matplotlib.use() is occurring. To find it you will have to trace back through your application, looking for the first place where pylab, matplotlib.pyplot, or matplotlib.backends is imported, or the first explicit use of matplotlib.use(), whichever is earliest.

Eric

What changed is that I added a warning where previously there was only a
silent error--the matplotlib.use command was being ignored. Sometimes
this (ignoring the command) is harmless, but it is never the user's intent
and in some cases it can cause puzzling problems. It often occurs when a
script or module does "from pylab import *" or "import pylab as P", and
then later "import matplotlib; matplotlib.use('Agg')". In this example,
the user intends to make plots non-interactively, writing them to files,
but the whole gui machinery for the default backend (e.g., gtkagg or wxagg
or tkagg) is imported unintentionally.

Eric,

   Thanks for the explanation. And you bring up another issue that I have:
the most appropriate way to generate non-interactive plots, written to
files, for inclusion in a ReportLab report. Do I want to use pylab for this,
plots embedded in wx, or something else?

   I need to get this module running properly so I am focusing on really
understanding how to use matplotlib to produce what we need.

One way to find out where the warning is coming from is to invoke your script as

python -Werror myscript.py

which will turn the warning into an error and thereby trigger an exception traceback.

   OK. Tomorrow morning I'll do this.

What this will *not* tell you is where the *earlier* call to
matplotlib.use() is occurring. To find it you will have to trace back
through your application, looking for the first place where pylab,
matplotlib.pyplot, or matplotlib.backends is imported, or the first
explicit use of matplotlib.use(), whichever is earliest.

   There are two modules in which pylab is used: reports.py and functions.py.
The former calls specific matplotlib functions in the latter.

   On the other hand, matplotlib is imported in several modules. Perhaps
that's the problem. I'll check this tomorrow, too.

Thanks,

Rich

···

On Fri, 1 Feb 2008, Eric Firing wrote:

--
Richard B. Shepard, Ph.D. | Integrity Credibility
Applied Ecosystem Services, Inc. | Innovation
<http://www.appl-ecosys.com> Voice: 503-667-4517 Fax: 503-667-8863

Eric,

   That did the trick. Two modules needed to have the backend specification
commented out.

Many thanks,

Rich

···

On Fri, 1 Feb 2008, Eric Firing wrote:

One way to find out where the warning is coming from is to invoke your script as

python -Werror myscript.py

--
Richard B. Shepard, Ph.D. | Integrity Credibility
Applied Ecosystem Services, Inc. | Innovation
<http://www.appl-ecosys.com> Voice: 503-667-4517 Fax: 503-667-8863

Rich Shepard wrote:

What changed is that I added a warning where previously there was only a
silent error--the matplotlib.use command was being ignored. Sometimes
this (ignoring the command) is harmless, but it is never the user's intent
and in some cases it can cause puzzling problems. It often occurs when a
script or module does "from pylab import *" or "import pylab as P", and
then later "import matplotlib; matplotlib.use('Agg')". In this example,
the user intends to make plots non-interactively, writing them to files,
but the whole gui machinery for the default backend (e.g., gtkagg or wxagg
or tkagg) is imported unintentionally.

Eric,

   Thanks for the explanation. And you bring up another issue that I have:
the most appropriate way to generate non-interactive plots, written to
files, for inclusion in a ReportLab report. Do I want to use pylab for this,
plots embedded in wx, or something else?

If you are generating plots non-interactively--that is, entirely in a script, so you don't need to see the plot on the screen to fiddle with it--then use a non-interactive backend. WxAgg, TkAgg, GtkAgg, QtAgg, etc. are needed only if you are working interactively. They don't necessarily hurt otherwise, but they don't help.

I have taken a quick look at the ReportLab documentation, and it looks like you are stuck with using PIL to import png files. (This means using the Agg backend.) If what you are plotting is image-like, this is not so bad, but it is not great in any case. It means things like text in your plot (axes ticks, labels, etc.) that should be getting into your final pdf in native form will instead get in as bit patterns, and this is bad for both quality and file size. Same for lines; it would be much better to generate vector graphics directly in your report. It would be nice to have something like a pdf-to-reportlab or svg-to-reportlab code generator, so you could use the pdf or svn matplotlib backend, and keep vectors as vectors.

If your matplotlib plots can be on separate pages, then you could use the pdf backend to generate those pages, and use pdftk to insert them among the pages generated by ReportLab.

Whether to use pylab is an entirely separate issue; it is a matter of programming style. The usual advice would be to use matplotlib.pyplot for a very few functions (figure, close, maybe a few others) and then use object-oriented style--that is, object method calls instead of functions--for everything else. There is nothing wrong with sticking with pylab or pyplot functions, though--they work fine.

   I need to get this module running properly so I am focusing on really
understanding how to use matplotlib to produce what we need.

One way to find out where the warning is coming from is to invoke your script as

python -Werror myscript.py

which will turn the warning into an error and thereby trigger an exception traceback.

   OK. Tomorrow morning I'll do this.

What this will *not* tell you is where the *earlier* call to
matplotlib.use() is occurring. To find it you will have to trace back

Note the following three lines carefully:

through your application, looking for the first place where pylab,
matplotlib.pyplot, or matplotlib.backends is imported, or the first
explicit use of matplotlib.use(), whichever is earliest.

Where and when matplotlib itself is imported doesn't matter--it is the events listed above that are relevant to your question.

Eric

···

On Fri, 1 Feb 2008, Eric Firing wrote:

   There are two modules in which pylab is used: reports.py and functions.py.
The former calls specific matplotlib functions in the latter.

   On the other hand, matplotlib is imported in several modules. Perhaps
that's the problem. I'll check this tomorrow, too.

Thanks,

Rich