An easier way to create figure and group of axes; useful?

Howdy,

in trying to teach a more structured use of mpl, I keep getting
annoyed by the whole figure(), add_subplot(), grab axes dance. I've
also seen students get confused by it. Does something along these
lines sound useful to have in the core (see attached)?

In use, below. You'd normally capture f, a = figaxes(...) to get the
figure and axes list, but I leave it off here for display purposes:

In [37]: figaxes()
Out[37]:
(<matplotlib.figure.Figure object at 0xa24b4cc>,
[<matplotlib.axes.AxesSubplot object at 0x9e74a4c>])

In [38]: figaxes((2,1))
Out[38]:
(<matplotlib.figure.Figure object at 0xa359fcc>,
[<matplotlib.axes.AxesSubplot object at 0xa47c66c>,
  <matplotlib.axes.AxesSubplot object at 0xa4a5c8c>])

In [39]: figaxes((2,2),dict(polar=True))
Out[39]:
(<matplotlib.figure.Figure object at 0xa6e340c>,
[<matplotlib.axes.PolarAxesSubplot object at 0xa6fd5ac>,
  <matplotlib.axes.PolarAxesSubplot object at 0xa8b73cc>,
  <matplotlib.axes.PolarAxesSubplot object at 0xa8dd54c>,
  <matplotlib.axes.PolarAxesSubplot object at 0xa9686cc>])

Feedback welcome.

Cheers,

f

fax.py (1014 Bytes)

Fernando Perez wrote:

in trying to teach a more structured use of mpl,

good for you!

I always felt that to efficiently use the OO interface, there needed to be some more utility functions like this:

In [37]: figaxes()
Out[37]:
(<matplotlib.figure.Figure object at 0xa24b4cc>,
[<matplotlib.axes.AxesSubplot object at 0x9e74a4c>])

In [38]: figaxes((2,1))
Out[38]:
(<matplotlib.figure.Figure object at 0xa359fcc>,
[<matplotlib.axes.AxesSubplot object at 0xa47c66c>,
  <matplotlib.axes.AxesSubplot object at 0xa4a5c8c>])

In [39]: figaxes((2,2),dict(polar=True))
Out[39]:
(<matplotlib.figure.Figure object at 0xa6e340c>,
[<matplotlib.axes.PolarAxesSubplot object at 0xa6fd5ac>,
  <matplotlib.axes.PolarAxesSubplot object at 0xa8b73cc>,
  <matplotlib.axes.PolarAxesSubplot object at 0xa8dd54c>,
  <matplotlib.axes.PolarAxesSubplot object at 0xa9686cc>])

I like it!

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@...236...

An effusive "yes, yes, good god yes!" from this mpl-devel lurker.

David

···

On 17-Feb-10, at 6:52 PM, Fernando Perez wrote:

Howdy,

in trying to teach a more structured use of mpl, I keep getting
annoyed by the whole figure(), add_subplot(), grab axes dance. I've
also seen students get confused by it. Does something along these
lines sound useful to have in the core (see attached)?

Thanks, that's two good pluses.

Any suggestions on name changes, or other fixes to make? Otherwise,
once I find a free minute I'll put it in.

Should it go into pyplot directly, or elsewhere and imported from
pyplot to expose it at the top-level? (I'm not overly familiar with
the layout of the whole library).

I'm also trying to show my students how *they* can improve their
tools; e.g. earlier this week a homework problem I wrote up led me to
a useful sympy patch that was quickly upstreamed:

http://git.sympy.org/?p=sympy.git;a=commit;h=507c4df6a9edfd5de5ad28535d1f9236db23bf04

and perhaps with this one we can do the same.

I hope that with a few of these examples, at least a few of them will
see the value of making the transition from pure user-mode to more
involved users/contributors (for context, this is a group of
scientists in Colombia with good computational skills but no tradition
of open source contributions; I'm hoping to help a little on this
front).

Cheers,

f

···

On Wed, Feb 17, 2010 at 7:27 PM, David Warde-Farley <dwf@...756...> wrote:

An effusive "yes, yes, good god yes!" from this mpl-devel lurker.

An effusive "yes, yes, good god yes!" from this mpl-devel lurker.

Thanks, that's two good pluses.

Any suggestions on name changes, or other fixes to make? Otherwise,
once I find a free minute I'll put it in.

I think the name "figsubplots" or "fig_subplots" is better because you
are creating Subplot instances. Alternatively, you might want to
consider simply "subplots" which returns just the list of subplots:
the figure can always be accessed as an attribute of the Subplot
instance::

  ax1, ax2, ax2, ax4 = subplots(2,2)
  fig = ax1.figure

Not sure that this is better; just a thought.

Should it go into pyplot directly, or elsewhere and imported from
pyplot to expose it at the top-level? (I'm not overly familiar with
the layout of the whole library).

pyplots is the right place for it since it is implicitly creating a
current figure and the only place where that magic happens is in
pyplot.

I'm also trying to show my students how *they* can improve their
tools; e.g. earlier this week a homework problem I wrote up led me to
a useful sympy patch that was quickly upstreamed:

This is a worthy goal. One use case I would like to see supported
is the sharex/sharey args::

  ax1 = fig.add_subplot(211)
  ax2 = fig.add_subplot(212, sharex=ax1)

If there is not an easy way to specify the shared axes with "figaxes"
or whatever it is called, I would not use it too often, because my
common case is multiple rows of subplots with a common x-axis.

One thing that will be nicer with the suggested patch is it makes it
easier to change a script where the subplot layout goes from 211 to
311 to 411 (this happens to me all the time as I find I want to plot
more stuff for a give time series). I have to change all the 311,
312, 313 to 411, 412, 413, and with your patch it would be a simple
change in one line from::

  ax1, ax2, ax3 = subplots(3,1)

to::

  ax1, ax2, ax3, ax4 = subplots(4,1)

Perhaps the solution to my sharex conundrum is to support an axes number, eg

  ax1, ax2, ax3, ax4 = subplots(4,1, sharex=1)

so all the subplots would have sharex with ax1.

JDH

JDH

···

On Wed, Feb 17, 2010 at 8:29 PM, Fernando Perez <fperez.net@...149...> wrote:

On Wed, Feb 17, 2010 at 7:27 PM, David Warde-Farley <dwf@...756...> wrote:

I think the name "figsubplots" or "fig_subplots" is better because you
are creating Subplot instances. Alternatively, you might want to
consider simply "subplots" which returns just the list of subplots:
the figure can always be accessed as an attribute of the Subplot
instance::

ax1, ax2, ax2, ax4 = subplots(2,2)
fig = ax1.figure

Not sure that this is better; just a thought.

Mmh, even I didn't know that, so I doubt my students would :slight_smile:

Idle thought: we've inherited the ugly 1-offset numbering scheme for
subplots from matlab, how about making fig_subplots return

[fig, ax1, ax2, ...]

This would at least make it easier to remember indexing, since

axN == ax[N]

would be true. It would also help with the shareax below, see rest of message...

Should it go into pyplot directly, or elsewhere and imported from
pyplot to expose it at the top-level? (I'm not overly familiar with
the layout of the whole library).

pyplots is the right place for it since it is implicitly creating a
current figure and the only place where that magic happens is in
pyplot.

OK.

I'm also trying to show my students how *they* can improve their
tools; e.g. earlier this week a homework problem I wrote up led me to
a useful sympy patch that was quickly upstreamed:

This is a worthy goal. One use case I would like to see supported
is the sharex/sharey args::

Sheesh, some people really want everything :slight_smile:

ax1 = fig.add_subplot(211)
ax2 = fig.add_subplot(212, sharex=ax1)

[...]

Perhaps the solution to my sharex conundrum is to support an axes number, eg

ax1, ax2, ax3, ax4 = subplots(4,1, sharex=1)

so all the subplots would have sharex with ax1.

That was what I had in mind, I just hadn't had time to try it. Here
it goes (since I started this while preparing class exercises, it's
now in the class git repo):

http://gfif.udea.edu.co/idf/indefero/www/index.php/p/mscomp-2010/source/tree/master/0217/figsubp.py

Comment away, I'll polish it later for mpl over svn, while waiting for
us to catch up with the XXth century and move over to git :slight_smile:

There are examples to try it out and see how it works (download link
at the bottom of that page).

Cheers,

f

···

On Wed, Feb 17, 2010 at 10:17 PM, John Hunter <jdh2358@...149...> wrote:

Yes, you should know better by now than to propose a minor enhancement....

Another thought about the interface. How about *just* returning the
figure instance, and let the users simply index into the axes list.
Then they can have their 0 based indexing because it is a python
list::

  fig = fig_subplot((2,1), sharex=1)
  fig.axes[0].plot(...)
  fig.axes[1].scatter(...)

mpl is creating this axes list anyway.... I'm also fine with your
implementation -- just a suggestion.

One other thing: I don't think a tuple is best for the axes
dimensionality. We always require two and exactly two shape arguments
(numrows, numcols) so we don't need the flexibility of the tuple in
the way that numpy.zeros does. And it is easier to type::

  fig_subplot(2, 1, sharex=1)

than::

  fig_subplot((2,1), sharex=1)

As the world master of keystroke efficiency, I would think you would
appreciate the savings! But again, if you prefer the tuple, I don't
have a problem with it. It does have the advantage of visually
suggesting a single shape argument.

JDH

···

On Wed, Feb 17, 2010 at 10:50 PM, Fernando Perez <fperez.net@...149...> wrote:

This is a worthy goal. One use case I would like to see supported
is the sharex/sharey args::

Sheesh, some people really want everything :slight_smile:

John Hunter wrote:

One other thing: I don't think a tuple is best for the axes
dimensionality. We always require two and exactly two shape arguments
(numrows, numcols) so we don't need the flexibility of the tuple in
the way that numpy.zeros does. And it is easier to type::

  fig_subplot(2, 1, sharex=1)

than::

  fig_subplot((2,1), sharex=1)

would we want to support:

   fig_subplot( (2,) )

If so, then a tuple has a real advantage. If not, then it doesn't make much difference, though I still prefer the tuple, as I can imagine that I might define that somewhere else, and it's handy to have it as a single object.

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@...236...

fig_subplot( (2,) ) is still more characters than fig_subplot( 2,1),
and more shifted characters which can be harder to type, but since
they are sequential with the function call parentheses in this case it
is probably not a problem. I'm not convinced by the "single object"
argument. To do something useful with the axes that are generated,
you probably will need in your code to know how many rows and columns
you have, so at some point you['ll need to define numrows and numcols
as variables anyhow.

Perhaps the following is the best:

  def fig_subplot(numrows=1, numcols=1, ...blah):

Since the most common use case is 1,1 followed by 2,1, one can write

  fig_subplot() # for 1,1
  fig_subplot(2) # for 2,1
  fig_subplot(numcols=2) # for 1,2

JDH

But it's not an important difference -- Fernando should just go with
what feels most natural to him

···

On Thu, Feb 18, 2010 at 11:05 AM, Christopher Barker <Chris.Barker@...236...> wrote:

John Hunter wrote:

fig_subplot( (2,) )

If so, then a tuple has a real advantage. If not, then it doesn't make
much difference, though I still prefer the tuple, as I can imagine that
I might define that somewhere else, and it's handy to have it as a
single object.

I thought there is no master and slave for an axis-sharing?
If that's the case, maybe "sharex=True" should be suffice?

Also, how about "subplots" returns a some kind of object so that we
may define some methods on it. We can define "__iter__" method so
that above syntax also works. As an example,

mysubplots = subplots(4,1, sharex=True)
mysubplots.label_outer()
ax1, ax2, ax3, ax4 = mysubplots

Regards,

-JJ

···

On Wed, Feb 17, 2010 at 10:17 PM, John Hunter <jdh2358@...149...> wrote:

Perhaps the solution to my sharex conundrum is to support an axes number, eg

ax1, ax2, ax3, ax4 = subplots(4,1, sharex=1)

Yes, you should know better by now than to propose a minor enhancement....

And you should know by know common sense has somehow been amputated

Another thought about the interface. How about *just* returning the
figure instance, and let the users simply index into the axes list.
Then they can have their 0 based indexing because it is a python
list::

fig = fig_subplot((2,1), sharex=1)
fig.axes[0].plot(...)
fig.axes[1].scatter(...)

mpl is creating this axes list anyway.... I'm also fine with your
implementation -- just a suggestion.

Mmh, doubting: the more compact api is appealing, but in actual use it
seems to make for a lot of typing, since the really useful objects for
most things are the axes. Given that in python3 we'll have more
flexible unpacking:

Python 3.1.1 (r311:74480, Sep 18 2009, 19:43:55)
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.

a = list(range(10))
x, y, *z = a
x, y, z

(0, 1, [2, 3, 4, 5, 6, 7, 8, 9])

m, *n, p, q = a
m, n, p, q

(0, [1, 2, 3, 4, 5, 6, 7], 8, 9)

makes me lean towards keeping the [fig, ax1, ax2...] notation. But
I'm willing to reconsider on further arguments.

One other thing: I don't think a tuple is best for the axes
dimensionality. We always require two and exactly two shape arguments
(numrows, numcols) so we don't need the flexibility of the tuple in
the way that numpy.zeros does. And it is easier to type::

fig_subplot(2, 1, sharex=1)

than::

fig_subplot((2,1), sharex=1)

As the world master of keystroke efficiency, I would think you would
appreciate the savings! But again, if you prefer the tuple, I don't
have a problem with it. It does have the advantage of visually
suggesting a single shape argument.

+1 for the (nr, nc, share...) form.

I won't have time to work on this for a couple of days though; keep
further feedback coming, I should be back home on Monday and able to
finish it (I'm away on a teaching-sprint-within-a-teaching-marathon
for a couple of days). If anyone wants to finish it first, run with
it., I'm not personally attached to it.

Cheers,

f

···

On Thu, Feb 18, 2010 at 8:02 AM, John Hunter <jdh2358@...149...> wrote:
from my system :slight_smile:

Howdy

I thought there is no master and slave for an axis-sharing?
If that's the case, maybe "sharex=True" should be suffice?

I defer to your wisdom here: I had no clue about this, so I went for
the clumsier API. If you are right, it would also make the
implementation much simpler, as I had to play some not-totally-obvious
gymnastics to alter axis creation order based on this parameter.

One more, related question: is it possible/reasonable to share *both*
x and y axes?

It would be really nice if you were correct. The api could be nicer
and the implementation simpler.

Also, how about "subplots" returns a some kind of object so that we
may define some methods on it. We can define "__iter__" method so
that above syntax also works. As an example,

mysubplots = subplots(4,1, sharex=True)
mysubplots.label_outer()
ax1, ax2, ax3, ax4 = mysubplots

Mmh, more than I have time for right now, I'm afraid (I'm really
pushing it with these little side-trips already). But if you do have
a minute to do it, run with it.

I can only commit to finish the basic implementation with the changes
discussed above, plus any fixes to share* based on clarifying these
points. A fancier object API would be great to have, so by all means
go ahead if you have the bandwidth!

Cheers,

f

···

On Thu, Feb 18, 2010 at 1:19 PM, Jae-Joon Lee <lee.j.joon@...149...> wrote:

I defer to your wisdom here: I had no clue about this, so I went for
the clumsier API. If you are right, it would also make the
implementation much simpler, as I had to play some not-totally-obvious
gymnastics to alter axis creation order based on this parameter.

After quickly going through the mpl source (and in my experience), I
think it is quite safe to assume that there is no master-slave
relation among the shared axes.

One more, related question: is it possible/reasonable to share *both*
x and y axes?

Yes, it is possible as I often do.

It would be really nice if you were correct. The api could be nicer
and the implementation simpler.

Also, how about "subplots" returns a some kind of object so that we
may define some methods on it. We can define "__iter__" method so
that above syntax also works. As an example,

mysubplots = subplots(4,1, sharex=True)
mysubplots.label_outer()
ax1, ax2, ax3, ax4 = mysubplots

Mmh, more than I have time for right now, I'm afraid (I'm really
pushing it with these little side-trips already). But if you do have
a minute to do it, run with it.

I can only commit to finish the basic implementation with the changes
discussed above, plus any fixes to share* based on clarifying these
points. A fancier object API would be great to have, so by all means
go ahead if you have the bandwidth!

I, personally, am more interested in implementing some form of a
general interface (base class) for a set of axes, although I have no
immediate plan. If I have a chance to work on this, I will try to
adjust those to work with well your code.

Regards,

-JJ

···

On Thu, Feb 18, 2010 at 11:50 PM, Fernando Perez <fperez.net@...149...> wrote:

Cheers,

f

OK, thanks for the feedback. I've just finalized it here:

http://gfif.udea.edu.co/idf/indefero/www/index.php/p/mscomp-2010/source/tree/master/0217/figsubp.py

Knowing now that the sharing doesn't have an actual master/slave
relationship (like the existing examples suggest since they appear to
require an explicit index for sharing), the actual implementation was
really trivial in the end. It might be a good idea to clarify this in
the main docs, the current examples make axis sharing look harder than
it actually is (all those tricks with order creation I was playing are
completely unnecessary).

If you all like this API, I'm happy to push into the real svn repo.

Final question: should I put the little demo code at the bottom that I
used for testing this up in an example file? I put some of that in
the docstring as an example, but not all to avoid clutter.

Cheers,

f

···

On Sat, Feb 20, 2010 at 3:50 PM, Jae-Joon Lee <lee.j.joon@...149...> wrote:

After quickly going through the mpl source (and in my experience), I
think it is quite safe to assume that there is no master-slave
relation among the shared axes.

One more, related question: is it possible/reasonable to share *both*
x and y axes?

Yes, it is possible as I often do.

OK, since I know people are busy, I took silence as acquiescence.
Committed in r8151, please let me know if I messed anything up and
I'll try to fix it. I'm used to the numpy docstring standard, but I
tried to adapt it to the mpl one by looking at the rest of pyplot,
let me know if it needs fine-tuning.

Cheers,

f

···

On Tue, Feb 23, 2010 at 10:14 PM, Fernando Perez <fperez.net@...149...> wrote:

Final question: should I put the little demo code at the bottom that I
used for testing this up in an example file? I put some of that in
the docstring as an example, but not all to avoid clutter.

Howdy,

OK, since I know people are busy, I took silence as acquiescence.
Committed in r8151, please let me know if I messed anything up and
I'll try to fix it. I'm used to the numpy docstring standard, but I
tried to adapt it to the mpl one by looking at the rest of pyplot,
let me know if it needs fine-tuning.

While chatting today with John, he suggested that a better api for
this would be to return an *array* of supblots, so that one could
index them with a[i,j] for the plot in row i, column j. I've
implemented this already, but before committing it, I have one doubt:
what to do when nrows==ncols==1, the single subplot case? I'm inclined
to return only the subplot instead of a one-element array, so that one
can say

f, a = fig_subplot()
a.plot(...)

instead of having to do

f, a = fig_subplot()
a[0].plot(...)

But this means the return value of the function would be:
- fig, axis if nr=nc=1
- fig, axis_array in all other cases.

so it's a bit ugly. I think this is a case where practicality beats
purity and my nose tells me to go for the less pretty but more
convenient api, but I'm happy to get feedback. The return code reads
currently:

    # Reshape the array to have the final desired dimension (nrow,ncol), though
    # discarding unneeded dimensions that equal 1. If we only have one
    # subplot, just return it instead of a 1-element array.
    if nplots==1:
        return fig, axarr[0]
    else:
        return fig, axarr.reshape(nrows, ncols).squeeze()

Once we settle this design decision, I'll update the docstring and
example and will post the patch for final review before committing.

Cheers,

f

···

On Wed, Feb 24, 2010 at 11:27 AM, Fernando Perez <fperez.net@...149...> wrote:

Fernando Perez wrote:

Howdy,

OK, since I know people are busy, I took silence as acquiescence.
Committed in r8151, please let me know if I messed anything up and
I'll try to fix it. I'm used to the numpy docstring standard, but I
tried to adapt it to the mpl one by looking at the rest of pyplot,
let me know if it needs fine-tuning.

While chatting today with John, he suggested that a better api for
this would be to return an *array* of supblots, so that one could
index them with a[i,j] for the plot in row i, column j. I've
implemented this already, but before committing it, I have one doubt:
what to do when nrows==ncols==1, the single subplot case? I'm inclined
to return only the subplot instead of a one-element array, so that one
can say

f, a = fig_subplot()
a.plot(...)

instead of having to do

f, a = fig_subplot()
a[0].plot(...)

But this means the return value of the function would be:
- fig, axis if nr=nc=1
- fig, axis_array in all other cases.

The behavior one wants depends on whether one is calling fig_subplot in a program in which the number of subplots could range from 0 to n, or whether the call is being made with the number of subplots hardwired. The latter may be most common, but the former seems like an important use case. I suggest providing a kwarg, e.g. "squeeze=True" as the default, to eliminate zero-size-dimensions from the array, and False for the case where nrows and/or ncols could be zero but one wants to be able to iterate over the resulting array regardless.

Eric

···

On Wed, Feb 24, 2010 at 11:27 AM, Fernando Perez <fperez.net@...149...> wrote:

so it's a bit ugly. I think this is a case where practicality beats
purity and my nose tells me to go for the less pretty but more
convenient api, but I'm happy to get feedback. The return code reads
currently:

    # Reshape the array to have the final desired dimension (nrow,ncol), though
    # discarding unneeded dimensions that equal 1. If we only have one
    # subplot, just return it instead of a 1-element array.
    if nplots==1:
        return fig, axarr[0]
    else:
        return fig, axarr.reshape(nrows, ncols).squeeze()

Once we settle this design decision, I'll update the docstring and
example and will post the patch for final review before committing.

Cheers,

f

------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

+1 This feels like a clean solution to the problem.

Ryan

···

On Thu, Mar 18, 2010 at 12:20 PM, Eric Firing <efiring@...229...> wrote:

Fernando Perez wrote:

While chatting today with John, he suggested that a better api for
this would be to return an *array* of supblots, so that one could
index them with a[i,j] for the plot in row i, column j. I've
implemented this already, but before committing it, I have one doubt:
what to do when nrows==ncols==1, the single subplot case? I'm inclined
to return only the subplot instead of a one-element array, so that one
can say

f, a = fig_subplot()
a.plot(...)

instead of having to do

f, a = fig_subplot()
a[0].plot(...)

But this means the return value of the function would be:
- fig, axis if nr=nc=1
- fig, axis_array in all other cases.

The behavior one wants depends on whether one is calling fig_subplot in
a program in which the number of subplots could range from 0 to n, or
whether the call is being made with the number of subplots hardwired.
The latter may be most common, but the former seems like an important
use case. I suggest providing a kwarg, e.g. "squeeze=True" as the
default, to eliminate zero-size-dimensions from the array, and False for
the case where nrows and/or ncols could be zero but one wants to be able
to iterate over the resulting array regardless.

--
Ryan May
Graduate Research Assistant
School of Meteorology
University of Oklahoma

Fernando Perez wrote:

While chatting today with John, he suggested that a better api for
this would be to return an *array* of supblots, so that one could
index them with a[i,j] for the plot in row i, column j.

That would be nice.

implemented this already, but before committing it, I have one doubt:
what to do when nrows==ncols==1, the single subplot case? I'm inclined
to return only the subplot instead of a one-element array, so that one
can say

f, a = fig_subplot()
a.plot(...)

instead of having to do

f, a = fig_subplot()
a[0].plot(...)
But this means the return value of the function would be:
- fig, axis if nr=nc=1
- fig, axis_array in all other cases.

actually, wouldn't there be three options, essentially:
scalar, 1-d, 2-d

so the second example might be.

f, a = fig_subplot()
a[0,0].plot(...)

Eric Firing wrote:

The behavior one wants depends on whether one is calling fig_subplot in a program in which the number of subplots could range from 0 to n, or whether the call is being made with the number of subplots hardwired.

good point.

The latter may be most common, but the former seems like an important use case. I suggest providing a kwarg, e.g. "squeeze=True" as the default, to eliminate zero-size-dimensions from the array, and False for the case where nrows and/or ncols could be zero but one wants to be able to iterate over the resulting array regardless.

this feels a bit ugly to me as well, though not too bad.

Maybe this is too much magic, but could you look at what was passed in to the subplot call:

I don't remember if you are following the figure.add_subplot() api, but:

If nothing, then the user is clearly asking for a single axis.

if (r,c,n) then the user is specifying a 2-d arrangement, even if r and c happen to be 1.

I think the only two options should be scalar or 2-d array, it seems a bit much to have a 1-d array option as well.

Also, IIUC correctly, Figure.add_subplot always returns a SINGLE axis -- you have to call it multiple times to get the whole set. Does this version return the whole set?

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@...236...

I disagree here -- if you are 2,1 or 1,2 rows x cols, 1D indexing is
natural. This is also the most common use case so the most important
to get right. If you aren't doing multiple subplots, a plain ol
subplot(111) may be preferred to fig_subplots anyhow.

JDH

···

On Thu, Mar 18, 2010 at 1:38 PM, Christopher Barker <Chris.Barker@...236...> wrote:

I think the only two options should be scalar or 2-d array, it seems a
bit much to have a 1-d array option as well.