7

In order to set the labels of an axis object, one uses the xticklabels method:

fig, ax = plt.subplots()
ax.imshow(np.eye(101))
labels = np.linspace(2, 4, 4)
ax.set_xticks([0, 33, 66, 100])
ax.set_xticklabels(labels)

Which gives:

1

It is also possible to format the labels using a formatter:

fig, ax = plt.subplots()
labels = np.linspace(2, 4, 4)
ax.imshow(np.eye(101))
ax.set_xticks([0, 33, 66, 100])
ax.set_xticklabels(labels)
ax.xaxis.set_major_formatter(FormatStrFormatter('%.2f'))

But the formatter only uses the tick position, and not his label:

2

The workaround is to manually format the labels before using set_xticklabels:

fig, ax = plt.subplots()
labels = ["{0:.1f}".format(x) for x in np.linspace(2, 4, 4)]
ax.imshow(np.eye(101))
ax.set_xticks([0, 33, 66, 100])
ax.set_xticklabels(labels)

3

So, there are two questions:

  1. Is it possible to format to the labels when using set_xticklabels function? For example, by using a format string.
  2. What is the link between set_xticklabels and the Formatter? It appears that the Formatter is not taking set_xticklabels at all into account, and produces the labels by itself.
Phylliade
  • 1,667
  • 4
  • 19
  • 27

3 Answers3

8

Setting the xticklabels is equivalent to using a FixedFormatter.

ax.set_xticklabels(ticks)

is the same as

ax.xaxis.set_major_formatter(matplotlib.ticker.FixedFormatter(ticks))

(see source code)

If you have set the ticklabels and then set a formatter, it will simply overwrite the previously set ticklabels. And vice versa.

Because set_xticklabels uses a FixedFormatter and not e.g. a FormatStrFormatter, you need to format the ticklabels yourself. In that sense, using a FormatStrFormatter might be the better method than using a preformatted list.

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
1

There is also another alternative, by using the extent parameter of the imshow function: If you just want an automatic position and format for the ticks, it will handle everything for you:

fig, ax = plt.subplots()
ax.imshow(np.eye(101), extent=[2, 4, 2, 4])

1

Just be careful to arrange your matrix in the good order: with extent, the minimum tick values on the x and y axes will always be on the bottom-left corner! (So matrix[-1, 0]).

Phylliade
  • 1,667
  • 4
  • 19
  • 27
1

By now (tested on matplotlib 3.4.2) you can also use the .format_ticks method of a Formatter.

ax.set_xticklabels(FormatStrFormatter('%.2f').format_ticks(ticks))

The Formatter formats the ticks before passing them to set_xticklabels.

Stefan_EOX
  • 1,279
  • 1
  • 16
  • 35