ticks & labels

I am having some trouble getting the ticks and labels on my plot to
match what I want and I was hoping that someone here would be able to
help. Here are what I want (on the yaxis):

logarithmic ticks with major ticks every order of magnitude but labels
ONLY every other magnitude. Additionally, I would like the labels to
be only the exponent (2 instead of 1e2 or 10^2). For the minor ticks,
I want a tick at all 9 values between the major ticks.

Here is what I have so far. For the minor ticks, I have
subsy=[1,2,3,4,5,6,7,8,9] as an argument for semilogy which seems to
work fine. To have labels every other magnitude I used
ticker.LogLocator(base=100.0), which gives me the labels where I want
them.

The two things I have been unable to figure out are how to add a major
tick at all of the other magnitudes (those without a label) and how to
change the format of the labels so that only the exponent is showing.
I'm sure both of these are straightforward, but I have been unable to
figure them out. Thanks for your help.

-Jeffrey

You can accomplish both in one swoop using a custom formatter instead
of a custom locator. That is, instead of using a
LogLocator(base=100.0) which isn't giving you ticks where you want
them, use the default log locator, and make a custom formatter to
suppress strings where you don't want them and to use the format you
want. Eg, something like

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

fig = plt.figure()
ax = fig.add_subplot(111)

N = 1000
x = np.arange(N)
y = np.random.rand(N)*1e8

ax.semilogy(x, y)

class MyFormatter(ticker.LogFormatter):

    def __call__(self, val, pos=None):
        fx = int(np.log(abs(val))/np.log(self._base) +0.5)
        isDecade = self.is_decade(fx)
        if not isDecade and self.labelOnlyBase:
            return ''
        if (fx%2)==1: # odd, skip
            return ''

        return '%d'%fx

ax.yaxis.set_major_formatter(MyFormatter())
plt.show()

···

On Mon, Aug 11, 2008 at 1:45 PM, Jeffrey Fogel <matplotlib@...2127...> wrote:

The two things I have been unable to figure out are how to add a major
tick at all of the other magnitudes (those without a label) and how to
change the format of the labels so that only the exponent is showing.
I'm sure both of these are straightforward, but I have been unable to
figure them out. Thanks for your help.

A minor comment.
John's code may give incorrect results when exponents are negative.
int() truncates a floating point argument towards zero, e.g.,
int(-1.5) == -1 not -2. I guess calling floor() before int() will
work.

       fx = int(np.floor(np.log(abs(val))/np.log(self._base) +0.5))

-JJ

···

On Mon, Aug 11, 2008 at 3:23 PM, John Hunter <jdh2358@...287...> wrote:

On Mon, Aug 11, 2008 at 1:45 PM, Jeffrey Fogel > <matplotlib@...2127...> wrote:

The two things I have been unable to figure out are how to add a major
tick at all of the other magnitudes (those without a label) and how to
change the format of the labels so that only the exponent is showing.
I'm sure both of these are straightforward, but I have been unable to
figure them out. Thanks for your help.

You can accomplish both in one swoop using a custom formatter instead
of a custom locator. That is, instead of using a
LogLocator(base=100.0) which isn't giving you ticks where you want
them, use the default log locator, and make a custom formatter to
suppress strings where you don't want them and to use the format you
want. Eg, something like

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

fig = plt.figure()
ax = fig.add_subplot(111)

N = 1000
x = np.arange(N)
y = np.random.rand(N)*1e8

ax.semilogy(x, y)

class MyFormatter(ticker.LogFormatter):

   def __call__(self, val, pos=None):
       fx = int(np.log(abs(val))/np.log(self._base) +0.5)
       isDecade = self.is_decade(fx)
       if not isDecade and self.labelOnlyBase:
           return ''
       if (fx%2)==1: # odd, skip
           return ''

       return '%d'%fx

ax.yaxis.set_major_formatter(MyFormatter())
plt.show()

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

Thanks John, that worked perfectly (with JJ's correction). I'm fairly
new to python and hadn't considered writing a separate class for it.

-Jeffrey

···

On Mon, Aug 11, 2008 at 3:53 PM, Jae-Joon Lee <lee.j.joon@...287...> wrote:

A minor comment.
John's code may give incorrect results when exponents are negative.
int() truncates a floating point argument towards zero, e.g.,
int(-1.5) == -1 not -2. I guess calling floor() before int() will
work.

      fx = int(np.floor(np.log(abs(val))/np.log(self._base) +0.5))

-JJ

On Mon, Aug 11, 2008 at 3:23 PM, John Hunter <jdh2358@...287...> wrote:

On Mon, Aug 11, 2008 at 1:45 PM, Jeffrey Fogel >> <matplotlib@...2127...> wrote:

The two things I have been unable to figure out are how to add a major
tick at all of the other magnitudes (those without a label) and how to
change the format of the labels so that only the exponent is showing.
I'm sure both of these are straightforward, but I have been unable to
figure them out. Thanks for your help.

You can accomplish both in one swoop using a custom formatter instead
of a custom locator. That is, instead of using a
LogLocator(base=100.0) which isn't giving you ticks where you want
them, use the default log locator, and make a custom formatter to
suppress strings where you don't want them and to use the format you
want. Eg, something like

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

fig = plt.figure()
ax = fig.add_subplot(111)

N = 1000
x = np.arange(N)
y = np.random.rand(N)*1e8

ax.semilogy(x, y)

class MyFormatter(ticker.LogFormatter):

   def __call__(self, val, pos=None):
       fx = int(np.log(abs(val))/np.log(self._base) +0.5)
       isDecade = self.is_decade(fx)
       if not isDecade and self.labelOnlyBase:
           return ''
       if (fx%2)==1: # odd, skip
           return ''

       return '%d'%fx

ax.yaxis.set_major_formatter(MyFormatter())
plt.show()

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options