tick-marks feature request

Hi All, My research group submitted a paper for

    > publication in a journal, and one of the requested changes
    > was having the tick-marks formatted like 1x10^\{\-4\} (for
    > the latex-ers out there) rather than 1e-4, which was
    > considered an unnecessary use of mathematical jargon. I
    > wasn't the lead author on this particular paper, and
    > therefore the plots were not created using Python and
    > MPL. But I think this is a pretty standard formatting
    > requirement in the scientific community. Would the
    > creators of Matplotlib consider an option to format the
    > ticks like this (does this capability exist and I havent
    > found it yet)?

Yes, this would be nice. Of course, you can manually format the ticks
using mathtext, eg,

    from matplotlib.matlab import *

    rc('tick', labelsize=15)

    a=[8E8,10E8, 15E8]
    plot(a,a)

    ticks = arange(8,16)
    labels = ['%d^\{8\}'%val for val in ticks]
    set(gca(), xticks=ticks*1e8, yticks=ticks*1e8,
               xticklabels=labels, yticklabels=labels)

    show()

but it would be nice to provide some automatic facilities for this.

    > In Matlab, when the tick labels require scientific
    > notation, only the decimal component is listed in each
    > tick label, and the exponential part is printed at the end
    > of the axis. In Igor, the exponential part can be included
    > in the y-axis label. Finally, one problem with formatting
    > tick labels is how to deal with data spanning small
    > ranges, but with large offsets, like
    > array(range(10))+1e10. Maybe there is an interest in
    > removing the offset from each tick label, and including it
    > elsewhere in the figure? Then again, maybe that's getting
    > too complicated.

This would definitely be a nice feature. It would require a little
architectural change in the formatter. Basically the formatter would
need to provide an additional method, eg get_offset, which would
return None (the current default) or a string like '10^\{\-23\}. The
axis, which calls the formatter, could check this value, and if not
None, render it to the proper place (eg left of x axis). I could help
you with this part. Below I'll include a script example showing how
to plot a tick offset which you can currently use for figures.
Basically, we'd just want to automate something along these lines.

    > Is this attractive to the Matplotlib Gurus and Users? If
    > so, is it something I could work on, or would it be best
    > left to the masters?

There's only one path to becoming a master, of course, which is to
dive in. It would be great if you work on this. Getting ticking
right is pretty hard since there are so many pathological cases out
there. But it looks like you work with that kind of data so you'll be
in a good position to find and fix the problem spots. I think you
should take two approaches: 1) clean up the existing Locators and
Formatters when you find bugs and 2) define some new ones. It
shouldn't be too hard to define a new formatter that does the mathtext
formatting for exponential ticking you've alluded to above.

The only (minor) downside to doing mathtext formatting is that the
font is likely different than non-mathtext on your figure. There are
two ways to solve this: use the cmr font as the default for the entire
figure or better, support mathtext layout (super/subscripting) for any
font. Right now we use the computer modern fonts for mathtext because
they have all the symbols, but there is no reason (other than time)
that we can't use the mathtext layout algorithms for
super/subscripting of non symbol fonts.

Let me know how I can help...

JDH

# use an exponential tick offset
from matplotlib.matlab import *

rc('tick', labelsize=12)

a=[8E8,10E8, 15E8]
plot(a,a)

ticks = arange(8,16)
labels = ['%d'%val for val in ticks]

# place the offset in axes coords
t = text(-.075, -.075, r'10^\{8\}\\times',
         transform=gca().transAxes,
         fontsize=14)
t.set_clip_on(False)

set(gca(), xticks=ticks*1e8, yticks=ticks*1e8,
    xticklabels=labels, yticklabels=labels)

show()