Hi,

2009/11/18 Jason Heeris <jason.hee...@gmail.com>:
> In gnuplot, I can do the following:
>
> set format x "%.0s %cHz"
>
> ...and this will set the x-axis labels (on a semilogx style plot) to
> be "10 Hz", "100 Hz", "1 kHz", "10 kHz", etc.

I ended up implementing this myself, it wasn't too hard. I've attached
the code if anyone else is interested. I don't know matplotlib that
well, so I don't know if there's much duplication of code in there.

I thought I'd CC the dev list in case others think it might be useful.
If not, sorry for the noise.

Cheers,
Jason
import math, decimal
from matplotlib.ticker import LogFormatter

# The SI engineering prefixes
ENG_PREFIXES = {
    -24: "y",
    -21: "z",
    -18: "a",
    -15: "f",
    -12: "p",
     -9: "n",
     -6: u"\u03BC", # Greek letter mu
     -3: "m",
      0: "",
      3: "k",
      6: "M",
      9: "G",
     12: "T",
     15: "P",
     18: "E",
     21: "Z",
     24: "Y"
  }

def format_eng(num, places=0):
    """ Formats a number in engineering notation, appending a letter
    representing the power of 1000 of the original number. Some examples:

    >>> format_eng(0, 0)
    '0'

    >>> format_eng(1000000, 1)
    '1.0 M'

    >>> format_eng("-1e-6", 2)
    u'-1.00 \u03bc'

    @param num: the value to represent
    @type num: either a numeric value or a string that can be converted to a
               numeric value (as per decimal.Decimal constructor)

    @param prec: the number of decimal places to include (default 0)
    @type prec: integer > 0

    @return: engineering formatted string
    """

    dnum = decimal.Decimal(str(num))

    sign = 1

    if dnum < 0:
        sign = -1
        dnum = -dnum

    if dnum != 0:
        pow10 = decimal.Decimal(int(math.floor(dnum.log10()/3)*3))
    else:
        pow10 = decimal.Decimal(0)

    pow10 = pow10.min(max(ENG_PREFIXES.keys()))
    pow10 = pow10.max(min(ENG_PREFIXES.keys()))

    prefix = ENG_PREFIXES[int(pow10)]

    mant = sign*dnum/(10**pow10)

    format_str = "%f %s"

    if places > 0:
        format_str = ("%%.%if %%s" % places)

    else:
        format_str = "%i %s"

    formatted = format_str % (mant, prefix)

    return formatted.strip()

class EngFormatter(LogFormatter):
    """
    Formats axis values using engineering prefixes to represent powers of 1000,
    plus a specified unit, eg. 10 MHz instead of 1e7.
    """

    def __init__(self, unit=""):
        LogFormatter.__init__(self, base=10)
        self.unit = unit

    def __call__(self, x, pos=None):

        # only label the decades
        b=self._base
        fx = math.log(abs(x))/math.log(b)
        isDecade = self.is_decade(fx)

        if not isDecade and self.labelOnlyBase:
            s = ''
        else:
            s = "%s%s" % (format_eng(x, 0), self.units)

        return self.fix_minus(s)

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Reply via email to