22

class matplotlib.ticker.FuncFormatter(func) The function should take in two inputs (tick value x and position pos) and return a string

def millions(x, pos):
    'The two args are the value and tick position'
    return '$%1.1fM' % (x*1e-6)

What happened to the pos parameter? It isn't even set to None.

I added print(pos) and got 0 1 2 3 4, plus a lot of None when I moved my mouse over the image. Only I don't know what to do with that information.

I have seen examples where x is used but not pos, and I don't understand how it is supposed to be used. Can someone give me an example? Thanks

Community
  • 1
  • 1
JMJ
  • 531
  • 1
  • 5
  • 16
  • 2
    Why the negative mark? What would be a better question? – JMJ Nov 09 '16 at 16:23
  • If `pos` is not `None` then you are asking for the text for a tick label. If pos _is_ `None` then the formatter is being called for some other reason (for example the mouse position text in the GUIs) – tacaswell Nov 09 '16 at 17:04
  • Ok, we have not None, but the function doesn't appear to be using the value. I thought the return string is what we use for the text for the tick label? Do you know how to make an example with the pos parameter used in the function? – JMJ Nov 09 '16 at 17:09
  • but it can if it wants to. – tacaswell Nov 09 '16 at 17:11
  • Yea... an example would really help. – JMJ Nov 09 '16 at 17:35

2 Answers2

13

Here is an example provided by Maplotlib documentations.

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

x = np.arange(4)
money = [1.5e5, 2.5e6, 5.5e6, 2.0e7]


def millions(x, pos):
    'The two args are the value and tick position'
    return '$%1.1fM' % (x*1e-6)

formatter = FuncFormatter(millions)

fig, ax = plt.subplots()
ax.yaxis.set_major_formatter(formatter)
plt.bar(x, money)
plt.xticks(x + 0.5, ('Bill', 'Fred', 'Mary', 'Sue'))
plt.show()

which produces

enter image description here

SparkAndShine
  • 17,001
  • 22
  • 90
  • 134
  • 1
    Yes, I have seen this but the pos in def millions(x, pos) isn't being used. Or if it is I don't understand the function enough to see it. – JMJ Nov 09 '16 at 16:25
  • 3
    @JMJ it's being used under the hood by matplotlib. user's don't need to worry about it. – Paul H Nov 09 '16 at 18:35
  • `ax.yaxis.set_major_formatter(millions)` is enough. – Suuuehgi Jul 03 '22 at 15:26
11

The FuncFormatter gives you a very flexible way to define your own (e.g. dynamic) tick label formatting to an axis.

Your custom function should accept x and pos parameters, where pos is the (positional) number of the tick label that is currently being formatted, and the x is the actual value to be (pretty) printed.

In that respect, the function gets called each time a visible tick mark should be generated - that's why you always get a sequence of function calls with positional argument starting from 1 to the maximal number of visible arguments for your axis (with their corresponding values).

Try running this example, and zoom the plot:

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

x = np.arange(4)
y = x**2


def MyTicks(x, pos):
    'The two args are the value and tick position'
    if pos is not None:
        tick_locs=ax.yaxis.get_majorticklocs()      # Get the list of all tick locations
        str_tl=str(tick_locs).split()[1:-1]         # convert the numbers to list of strings
        p=max(len(i)-i.find('.')-1 for i in str_tl) # calculate the maximum number of non zero digit after "."
        p=max(1,p)                                  # make sure that at least one zero after the "." is displayed
        return "pos:{0}/x:{1:1.{2}f}".format(pos,x,p)

formatter = FuncFormatter(MyTicks)

fig, ax = plt.subplots()
ax.yaxis.set_major_formatter(formatter)
plt.plot(x,y,'--o')
plt.show()

The result should look like this:

Example image

Bitstream
  • 111
  • 1
  • 6