On Wed, Nov 17, 2010 at 3:52 PM, Michael Droettboom <md...@stsci.edu> wrote:

>  On 11/17/2010 03:41 PM, Kynn Jones wrote:
>
>  Hi.  I am finding that matplotlib does not allow me to decouple certain
> actions from the GUI as much as I'd like.
>
>  For example, I have not been able to do any of the following tasks.  Some
> of these tasks are certainly artificial, but they all succinctly
> illustrate some of the problems I've been running into when doing more
> realistic stuff.
>
>  1. *without bringing up any GUI window*,
>
> Set the backend to a non-GUI backend, such as agg, pdf, ps, svg or cairo by
> setting the 'backend' rcParam in matplotlibrc, or doing:
>
>   import matplotlib
>   matplotlib.use("Agg") # Must be the first call after importing matplotlib
>
>    generate a list of all the filetypes available to a specific matplotlib
> installation for saving graphics (e.g. .ps, .svg, .pdf, .png, etc.);
>
> >From a figure object:
>
>    figure.canvas.get_supported_filetypes()
>
> returns a dictionary of supported file extensions, with mapping to more
> detailed descriptions of each.
>

Yes, but this solves the problem only for the non-GUI backends.  It does not
work for GUI backends, or at least for the MacOSX backend, which is the only
graphics backend that I've managed to get to work (despite of, literally,
days trying unsuccessfully to install other ones).  With this GUI backend,
as far as I know, generating a figure object (even an empty one), causes the
window to pop up.

That's the point of this task: to illustrate that even something like
getting a list of supported files, which does not require any graphical
output, is nonetheless tightly coupled with displaying the GUI.  As far as I
can tell, there's simply no way to get these filetypes for GUI backends
without bringing up a window.  (I'm assuming here that the MacOSX backend is
representative in this respect.)

By the same token, it is not possible to iterate over all the possible
backends within the same script to find the filetypes they support, because
the call to matplotlib.use(BACKEND) must happen before one imports
matplotlib.pyplot, which is required to generate the figure.canvas to
interrogate for possible filetypes.  This is another illustration of what I
refer to a tight coupling with the GUI.

>  2. switch back-and-forth between sending graphics objects for display to
> the GUI and sending them for saving to any of the available filetypes (as
> defined in (1));
>
> Once set to any of the GUI backends, you can use "show()" and "savefig()"
> interchangeably.
>

Yes, but only for the filetypes associated with that backend; once the GUI
backend is chosen, it blocks any other backend (even a non-GUI one) from
loading.  I'd argue that this is another example of tight coupling with the
GUI, because there's no reason why making a choice of GUI should restrict
the filetypes that can be saved.  The problems of displaying a graphic and
saving a file are completely orthogonal.  Picking a solution for one should
have no impact at all on what one chooses for the other.

> 3. (by far the most important one) *without activating any backend*, create
> a graphics object (I explain what I mean by this below).
>
>  To clarify what I mean by (3), the best I can do is to give an example
> from Mathematica.  In Mathematica, a Graphics object does not need to be
> displayed.  It can be defined as a collection of Graphics primitives,
> without ever displaying it in the GUI.  One such definition would be
> something like
>
>  In[1]:= g = Graphics[Line[{{1., 2.}, {2., 3.}, {3., 5.}}]];
>
>  This is what I mean in (3) by creating a graphics object without
> displaying it (in the GUI).  From a design perspective, this makes a lot of
> sense, since a Graphics object, as an idea, is entirely independent of
> whatever mean one chooses to display it.  I want my code to reflect this
> conceptual independence.
>
>  Regarding task (2), to make it more concrete, consider this (also
> artificial) exercise: write a script that iterates over all filetypes
> identified in (1); at each iteration, generate some random graphic (e.g. of
> the sort shown here
> http://matplotlib.sourceforge.net/examples/api/patch_collection.html),
> display it on the GUI, and save it as a file of the type corresponding to
> the iteration.
>
>  I would very much appreciate some hints/guidance on how to solve them.
>
>  As I noted, by far the most important of these tasks is (3).  From
> looking into the matplotlib source code, it looks to me impossible to do
> this with standard matplotlib functions.  But I am very much of a noob with
> mpl, so I still hope there's a way.
>
>  In the worst case scenario (i.e. (3) can't be done directly using
> standard mpl functions), then the only solution that I can think of would
> involve implementing a separate layer of abstract graphics objects, distinct
> from mpl's.  This layer would then delegate to mpl the task of displaying
> the graphics objects whenever the user requests it.  Any suggestions on how
> best to do this would be much appreciated.  In particular, I'd like to know
> what would be the right place to insert this new graphics object layer into
> the matplotlib objects stack.  I think it would be best to make this
> connection at a level deeper than the axes object, but I'm not quite sure
> how to do this.
>
> I think you'll find matplotlib works exactly as you want.  I think you
> might find this part of the documentation useful:
>
> http://matplotlib.sourceforge.net/faq/installing_faq.html#backends
>

I'd read that before (that's where I learned the little I know about
backends).

Still, I don't see how one does (3).  Here's an example problem:

1. generate (without bringing up a GUI window!) two different graphics
objects, each corresponding to a unit circle;
2. perform a random translation/scaling transformation on each of the two
circles;
3. combine the two circles into a single graphic object (so that they have a
common coordinate system);
4. finally, display the resulting object.

As far as I can tell, steps 1-3 cannot be done before choosing (and locking
in) a specific backend.  If this backend is a GUI one (or at least the
MacOSX one), then just carrying out (1) will cause a window to pop up.

~kj
------------------------------------------------------------------------------
Beautiful is writing same markup. Internet Explorer 9 supports
standards for HTML5, CSS3, SVG 1.1,  ECMAScript5, and DOM L2 & L3.
Spend less time writing and  rewriting code and more time creating great
experiences on the web. Be a part of the beta today
http://p.sf.net/sfu/msIE9-sfdev2dev
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Reply via email to