Setting tick labels for matshow

"Stan West" <stan.west-qqJZlXDiQIP5oiiGuJUvLw@...1455...> writes:

From: Nikolaus Rath [mailto:Nikolaus-BTH8mxji4b0@…1455…]
Sent: Saturday, October 30, 2010 16:17

but if I try to do the same think with the Y axis, everything looks
messed up (e.g. the matrix is no longer square):

The matrix remains square for me using a build from Subversion. What's your
matplotlib.__version__?

In [16]: matplotlib.__version__
Out[16]: '1.0.0'

I attached the result of fig.savefig(). Let's see if it makes it through
the list.

Best,

   -Nikolaus

test.png

···

--
»Time flies like an arrow, fruit flies like a Banana.«

  PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6 02CF A9AD B7F8 AE4E 425C

From: Nikolaus Rath [mailto:Nikolaus@…3072…]
Sent: Tuesday, November 02, 2010 21:38

In [16]: matplotlib.__version__
Out[16]: '1.0.0'

I attached the result of fig.savefig(). Let's see if it makes
it through
the list.

The bug in question was fixed at revision 8652, after 1.0.0 was released. The
distinction between the x and y axes in your case is because the y axis is
inverted.

You can work around the bug by avoiding the Axes.set_xticks() and set_yticks()
methods and instead setting the tick locator and formatter [1] for each axis.
(That's what set_xticks and set_yticks do, in addition to other conveniences
wherein the bug lies.) This would look something like:

    import matplotlib.ticker as mticker
    
    # (Plot here.)

    tick_locs = 2 * np.arange(len(modes)) + 0.5
    tick_labels = ['%d/%d' % (x[1], x[0]) for x in modes]
    for axis in (ax.xaxis, ax.yaxis):
        axis.set_major_locator(mticker.FixedLocator(tick_locs))
        axis.set_major_formatter(mticker.FixedFormatter(tick_labels))

Separately, because you're ticking on the element boundaries instead of
centers, you might consider passing a custom extent to matshow, as in

    N = 5
    res = np.diag(np.arange(2 * N))
    modes = [ (x+1, 0) for x in range(N) ]
    cs = ax.matshow(res, extent=[-0.5, N - 0.5, N - 0.5, -0.5])

Then you can simply tick on the integers, using

    tick_locs = np.arange(N)

I hope that helps.

[1] http://matplotlib.sourceforge.net/api/ticker_api.html