Hi -

I ended up with the code below, using Chloe's previously posted 'subcolormap' and, in order to make the colorbar nicely attached to the main imshow plot, I use make_axes_locatable in order to generate the colorbar axes. I tried it out with a couple of use-cases and it seems to do what it is supposed to, (with ticks only for the edges of the range of the data and 0, if that is within that range), but I am not entirely sure. Do you think it works?


Cheers,

Ariel
   
    from mpl_toolkits.axes_grid import make_axes_locatable

    fig=plt.figure()
    ax_im = fig.add_subplot(1,1,1)
    divider = make_axes_locatable(ax_im)
    ax_cb = divider.new_vertical(size="20%", pad=0.2, pack_start=True)
    fig.add_axes(ax_cb)
    #Extract the minimum and maximum values for scaling of the colormap/colorbar:
    max_val = np.max(m[np.where(m<1)])
    min_val = np.min(m)

    #This makes sure that 0 is always the center of the colormap:
    if min_val<-max_val:
        ax_max = -min_val
        ax_min = min_val
    else:
        ax_max = max_val
        ax_min = -max_val
 
    #Keyword args to imshow:
    kw = {'origin': 'upper',
          'interpolation': 'nearest',
          'cmap':cmap,
          'vmin':ax_min,
          'vmax':ax_max}
   
    im=ax_im.imshow(m,**kw)

    #The following produces the colorbar and sets the ticks
    if colorbar:
        delta = ax_max-ax_min #The size of the entire interval of data
        min_p = (min_val-ax_min)/delta
        max_p = (max_val-ax_min)/delta
        print min_p
        print max_p
        cnorm = mpl.colors.Normalize(vmin=min_val,vmax=max_val)
        subcmap = subcolormap(min_p,max_p,cmap)
        cb = mpl.colorbar.ColorbarBase(ax_cb, cmap=subcmap,
                                       orientation='horizontal',norm=cnorm)

        #Set the ticks - if 0 is in the interval of values, set that, as well
        #as the maximal and minimal values:
        if min_val<0:
            cb.set_ticks([min_val,0,max_val])
            cb.set_ticklabels(['%.2f'%min_val,'0','%.2f'%max_val])
        #Otherwise - only set the minimal and maximal value:
        else:
            cb.set_ticks([min_val,max_val])
            cb.set_ticklabels(['%.2f'%min_val,'%.2f'%max_val])



On Mon, Mar 29, 2010 at 6:41 AM, Friedrich Romstedt <friedrichromstedt@gmail.com> wrote:
2010/3/29 Friedrich Romstedt <friedrichromstedt@gmail.com>:
> Note that the ticking is a bit weird, there is also a bug in
> matplotlib I will report on right after this e-mail, whose bugfix you
> will maybe want to apply to get ticking properly working.  When you
> have insane values for C.min() and C.max() anyway, I'm afraid you have
> to retick manually with *ticks* to colorbar().  The ticker.MaxNLocator
> is only used when not using the *boundaries* arg to colorbar(),
> unfortunately.  Otherwise it tries to create maximal many and less
> than 11 ticks by using the lowest value and an appropriate step in
> *boundaries*.  I think the implementation of ticking is cumbersome and
> never optimal.

You can get rid of this night mare by giving the kwarg "ticks =
matplotlib.ticker.MaxNLocator()" to fig.colorbar().  Then the
*boundaries* aren't used for ticking (but still for plotting).

Friedrich



--
Ariel Rokem
Helen Wills Neuroscience Institute
University of California, Berkeley
http://argentum.ucbso.berkeley.edu/ariel