Several patches: kwargs cleanup, legend-kwargs, legend-fontsize

Hi there, again a few patches, mostly independent but

    > somewhat interconnected:

Hi Norbert, thanks for the patches. I applied these, but used a
somewhat different strategy for legend kwargs. Details below.

    > axes-kwargs: a general cleanup of the code in axes.py -
    > in several places, kwargs was handled inconsistently,
    > ignoring surplus arguments. I went through all uses of
    > kwargs and made sure that every argument is either used
    > or reported as error

There was a bug in the pcolor patch of the axes kwargs

        alpha = kwargs.pop('alpha', 1.0)
        norm = kwargs.pop('norm')
        cmap = kwargs.pop('cmap')
        vmin = kwargs.pop('vmin')
        vmax = kwargs.pop('vmax')

pop doesn't return a default value like get does, so if you want to
default to None (which we do here) you must explicitly return it

        norm = kwargs.pop('norm', None)
        cmap = kwargs.pop('cmap', None)

  ...etc...

I only caught this bug when I ran examples/backend_driver.py, which
runs many test scripts across many backends, and it is good to make
sure you can run this w/o errors after any non-trivial patch. Just
wanted to make you aware of it.

    > legend-fontsize: a tiny hack to make Legend respect the
    > FONTSIZE parameter correctly. (up to now, it was plainly
    > ignored)

    > legend-kwargs: have Legend.__init__ respect a bunch of
    > kwargs, overriding the global defaults. Also Axes.legend
    > passes these arguments through correctly

For kwargs, my general approach is to make them explicit in their
final target, eg in this case Legend.__init__. So rather than do

    def __init__(self, parent, handles, labels, loc, isaxes=True, **kwargs):
        Artist.__init__(self)
        if is_string_like(loc) and not self.codes.has_key(loc):
            verbose.report_error('Unrecognized location %s. Falling back on upper right; valid locations are\n%s\t' %(loc, '\n\t'.join(self.codes.keys())))
        if is_string_like(loc): loc = self.codes.get(loc, 1)
        
        self.NUMPOINTS = kwargs.pop('numpoints',self.NUMPOINTS)
        self.FONTSIZE = kwargs.pop('fontsize',self.FONTSIZE)
        self.PAD = kwargs.pop('pad',self.PAD)
        self.LABELSEP = kwargs.pop('labelsep',self.LABELSEP)
        self.HANDLELEN = kwargs.pop('handlelen',self.HANDLELEN)
        self.HANDLETEXTSEP = kwargs.pop('handletextsep',self.HANDLETEXTSEP)
        self.AXESPAD = kwargs.pop('axespad',self.AXESPAD)
        if len(kwargs):
            raise TypeError, 'Unknown argument "%s"'%kwargs.keys()[0]

I think it's better to do make them explicit

    def __init__(self, parent, handles, labels, loc,
                 isaxes=True,
                 numpoints = 4, # the number of points in the legend line
                 prop = FontProperties(size='smaller'),
                 pad = 0.2, # the fractional whitespace inside the legend border
                 # the following dimensions are in axes coords
                 labelsep = 0.005, # the vertical space between the legend entries
                 handlelen = 0.05, # the length of the legend lines
                 handletextsep = 0.02, # the space between the legend line and legend text
                 axespad = 0.02, # the border between the axes and legend edge

                 ):

because then it is self documenting in the python doc string and
clearer to someone trying to grok the code.

I use the **kwargs approach in methods that are simple thin wrappers
of the ultimate target, eg Axes.legend and matplotlib.matlab.legend.

So this is the approach I took in CVS. I also think I fixed the
fontsize default property issue with the use of prop as a kwarg.

Give it a test drive, and thanks for the patches!

JDH

John Hunter schrieb:

"Norbert" == Norbert Nemec <Norbert.Nemec.list@...159...> writes:

    > Hi there, again a few patches, mostly independent but
    > somewhat interconnected:

Hi Norbert, thanks for the patches. I applied these, but used a
somewhat different strategy for legend kwargs. Details below.

    > axes-kwargs: a general cleanup of the code in axes.py -
    > in several places, kwargs was handled inconsistently,
    > ignoring surplus arguments. I went through all uses of
    > kwargs and made sure that every argument is either used
    > or reported as error

There was a bug in the pcolor patch of the axes kwargs

        alpha = kwargs.pop('alpha', 1.0)
        norm = kwargs.pop('norm')
        cmap = kwargs.pop('cmap') vmin = kwargs.pop('vmin')
        vmax = kwargs.pop('vmax')

pop doesn't return a default value like get does, so if you want to
default to None (which we do here) you must explicitly return it

        norm = kwargs.pop('norm', None)
        cmap = kwargs.pop('cmap', None)

  ...etc...

Quick heads-up:

planck[~]> ip
Python 2.3.3 (#1, May 7 2004, 10:31:40)
Type "copyright", "credits" or "license" for more information.

IPython 0.6.5.cvs -- An enhanced Interactive Python.
? -> Introduction to IPython's features.
%magic -> Information about IPython's 'magic' % functions.
help -> Python's own help system.
object? -> Details about 'object'. ?object also works, ?? prints more.

In [1]: a={1:2,3:4}

In [2]: a.p
a.pop a.popitem

BUT (note python version number below):

haar[~]> ip
Python 2.2.3 (#1, Oct 15 2003, 23:33:35)
Type "copyright", "credits" or "license" for more information.

IPython 0.6.5.cvs -- An enhanced Interactive Python.
? -> Introduction to IPython's features.
%magic -> Information about IPython's 'magic' % functions.
help -> Python's own help system.
object? -> Details about 'object'. ?object also works, ?? prints more.

In [1]: a={1:2,3:4}

In [2]: a.popitem

Python 2.2 dicts do NOT have a pop() method, this appeared in python 2.3. It's fine if you decide to make matplotlib fully 2.3-dependent, but I just wanted to make you at least aware of this fact. 2.2 is still in reasonably wide use in the field, so if you are going to drop support for it, you might want to put a big fat warning about this fact, just to save users the hassle of weird bugs.

Best,

f