Hi,

There is a difference in the behaviour of Axes.hlines() vs

Axes.vlines(), in that vlines() lets you supply scalars for ymin and

ymax, whereas hlines() doesn't (for xmin and xmax). The patch below

fixes that, and also what looks like a separate bug in vlines. There

are also other differences, around units, but I haven't worked with that

area of matplotlib so will leave that for others.

I was wondering, though, whether there'd be any support for some work

which tidied up the near-duplicate code in axes.py. I've been playing

around with an approach using python's metaclass support, which, for

example, would replace the definitions of the two near-identical

functions set_xscale() and set_yscale() with the one meta-definition:

@MC_Traited.construct_traited_variants

def set__AXISLETTER_scale(self, value, base_AXISLETTER_ = 10, subs_AXISLETTER_ = None):

"""

SET_%(axis_letter_UC)sSCALE(value, base%(axis_letter)s = 10, subs%(axis_letter)s = None)

Set the %(axis_letter)s-scaling: 'log' or 'linear'

If value is 'log', the additional kwargs have the following meaning

* base%(axis_letter)s: base of the logarithm

* subs%(axis_letter)s: a sequence of the location of the minor ticks;

None defaults to autosubs, which depend on the number of

decades in the plot. Eg for base 10, subs%(axis_letter)s = (1, 2, 5) will

put minor ticks on 1, 2, 5, 11, 12, 15, 21, ....

To turn off minor ticking, set subs%(axis_letter)s = []

ACCEPTS: ['log' | 'linear']

"""

assert(value.lower() in ('log', 'linear'))

my_axis = _TRAITS_.my_axis(self)

if value == 'log':

my_axis.set_major_locator(LogLocator(base_AXISLETTER_))

my_axis.set_major_formatter(LogFormatterMathtext(base_AXISLETTER_))

my_axis.set_minor_locator(LogLocator(base_AXISLETTER_, subs_AXISLETTER_))

_TRAITS_.get_my_func(self.transData).set_type(LOG10)

minval, maxval = _TRAITS_.get_my_lim(self)

if min(minval, maxval) <= 0:

self.autoscale_view()

elif value == 'linear':

my_axis.set_major_locator(AutoLocator())

my_axis.set_major_formatter(ScalarFormatter())

my_axis.set_minor_locator(NullLocator())

my_axis.set_minor_formatter(NullFormatter())

_TRAITS_.get_my_func(self.transData).set_type(IDENTITY)

I haven't quite worked through the details, but it looks like it would

cut nearly 400 lines off axes.py (while adding c.200 lines of supporting

code), as well as avoid the type of inconsistency seen in hlines/vlines.

If there's interest, I'll post what I've got so far for comments.

Thanks,

Ben.

- - - - 8< - - - -

--- ORIG/axes.py 2007-07-17 15:24:10.367402000 +0100

+++ NEW/axes.py 2007-07-17 15:38:03.705394000 +0100

@@ -2325,6 +2325,11 @@

xmin = asarray(xmin)

xmax = asarray(xmax)

+ if len(xmin)==1:

+ xmin = xmin*ones(y.shape, typecode(y))

+ if len(ymax)==1:

+ xmax = xmax*ones(y.shape, typecode(y))

## ···

+

if len(xmin)!=len(y):

raise ValueError, 'xmin and y are unequal sized sequences'

@@ -2418,7 +2423,7 @@

minx = nx.amin(x)

maxx = nx.amax(x)

miny = min(nx.amin(ymin), nx.amin(ymax))

- maxy = max(nx.amax(ymax), nx.amax(ymax))

+ maxy = max(nx.amax(ymin), nx.amax(ymax))

minx, maxx = self.convert_xunits((minx, maxx))

miny, maxy = self.convert_yunits((miny, maxy))

corners = (minx, miny), (maxx, maxy)