colorbar patch

Here's a patch against 0.83.2 that modifies colorbar to use

    > contourf instead of imshow (so that only those colors used
    > by contourf are shown on the colorbar). It also adds a few
    > keyword options to colorbar to 1) allow for linear spacing
    > of colors on the colorbar (even if the contour levels are
    > not linear), and 2) draw lines on the colorbar between the
    > individual colors. Eric and Jim: I think you have both been
    > hacking on colorbar, perhaps we could merge your changes
    > into this patch? Otherwise, if no one has any objections,
    > I'll commit this to CVS later this week.

I haven't tested this but I did read over it and have one minor
comment

I tend to avoid catching all exceptions as in

+ try:
+ # mappable image is from contourf
+ clevs = array(mappable.levels.tolist() + [mappable.level_upper])
+ iscontourf = True
+ except:
+ # from imshow or pcolor.
+ iscontourf = False
+ norm = mappable.norm
+ if norm.vmin is None or norm.vmax is None:
+ mappable.autoscale()
+ cmin = norm.vmin
+ cmax = norm.vmax
+ clevs = linspace(cmin, cmax, cmap.N)

because they can lead to hard to track bugs. I suggest either
catching an AttributeError or testing explicitly for ContourMappable,
eg

if isinstance(mappable, ContourMappable):
   # do something
elif isinstance(mappable, ScalarMappable):
   # do something else
else:
   Raise TypeError("don't know how to handle type %s"%type(mappable))

Thanks,
JDH

Jeff,

I agree with John's comments.

Based on a look at the code, but no testing, it looks like your patch is well along the way. I don't have anything ready to merge with it now, but I think I could work on it a bit this weekend, if that would help.

One thing I would look at is the handling of the color spacing and the ticks and tick labelling. Allowing linear spacing is a good idea, but we may need more than a single binary kwarg: either two kwargs, or one with string arguments to allow more choice. Specifically, in my experience, it is often useful to give clevels like this: [-100] + frange(-5, 5) + [100]. The middle range may or may not be linear, but the two end points have arbitrary very large absolute values to ensure they will catch the extremes in the dataset. This is also the case for which Phil is requesting triangles at the ends, I think. In my Matlab code, I don't bother drawing triangles (which have a certain logic and appeal, but would make the colorbar code substantially more complicated); instead I simply make the first and last color patch have the length of the average of their immediate neighbors. Then I don't put a tick or label at the ends of the colorbar, but instead start and end at the second and next-to-last clev.

Another aspect I customized for Matlab, and would like to do for mpl, is in selecting the size and shape of the colorbar. To my eye, plots look much nicer, and are just as functional, with colorbars smaller in both dimensions than the present default. Any possible change in this aspect, however, would be independent of your changes to support discrete colorbars, and would probably best be left for a separate patch.

A Matlab example illustrating both the different treatment of end-intervals and the altered sizing is http://moli.soest.hawaii.edu/nbpalmer/np0305a/cont_a.html

In any case, I don't want to hold you up; you've made great progress, and the result looks useful as-is.

Eric

John Hunter wrote:

···

"Jeff" == Jeff Whitaker <jswhit@...196...> writes:

    > Here's a patch against 0.83.2 that modifies colorbar to use
    > contourf instead of imshow (so that only those colors used
    > by contourf are shown on the colorbar). It also adds a few
    > keyword options to colorbar to 1) allow for linear spacing
    > of colors on the colorbar (even if the contour levels are
    > not linear), and 2) draw lines on the colorbar between the
    > individual colors. Eric and Jim: I think you have both been
    > hacking on colorbar, perhaps we could merge your changes
    > into this patch? Otherwise, if no one has any objections,
    > I'll commit this to CVS later this week.

I haven't tested this but I did read over it and have one minor
comment

I tend to avoid catching all exceptions as in

+ try:
+ # mappable image is from contourf
+ clevs = array(mappable.levels.tolist() + [mappable.level_upper])
+ iscontourf = True
+ except:
+ # from imshow or pcolor.
+ iscontourf = False
+ norm = mappable.norm
+ if norm.vmin is None or norm.vmax is None:
+ mappable.autoscale()
+ cmin = norm.vmin
+ cmax = norm.vmax
+ clevs = linspace(cmin, cmax, cmap.N)

because they can lead to hard to track bugs. I suggest either
catching an AttributeError or testing explicitly for ContourMappable,
eg

if isinstance(mappable, ContourMappable):
   # do something
elif isinstance(mappable, ScalarMappable):
   # do something else
else:
   Raise TypeError("don't know how to handle type %s"%type(mappable))

Thanks,
JDH