Skip to main content
 首页 » 编程设计

python之'重新排序'/适应 matshow 矩阵图的刻度

2025年05月04日10zhwl

我已经很努力了,但我还是被 matplotlib 卡住了。请忽略,mpl 文档让我有点困惑。我的问题涉及以下方面:

  1. 我用 matshow 函数画了一个对称的 n*n 矩阵 D。行得通。

  2. 我想做同样的事情,只是 D

    中的(n)项的顺序不同
    D = [:,neworder] 
    D = [neworder,:] 
    

现在,我如何让报价重现这个新订单,最好另外使用 MaxNLocator?

据我了解...

set_xticklabels 按顺序为刻度分配标签,与刻度设置的位置无关?! set_xticks(mpl 文档:“使用刻度列表设置 x 刻度”)这里我真的不确定它的作用。有人可以准确解释吗?我不知道,这些功能对我的情况是否有帮助。甚至使用普通的 xy 图和 matshow 之间的事情也可能有所不同。

import numpy as np 
import matplotlib.pyplot as plt 
 
fig = plt.figure() 
ax = fig.gca() 
 
D = np.arange(100).reshape(10,10) 
 
neworder = np.arange(10) 
np.random.shuffle(neworder) 
 
D = D[:,neworder] 
D = D[neworder, :] 
 
# modify ticks somehow... 
 
ax.matshow(D) 
plt.show() 

引用保罗的回答,我想我试过了这样的事情。使用 neworder 定义位置并将其用于标签,我添加了 plt.xticks(neworder, neworder) 作为刻度修饰符。例如 neworder = [9 8 4 7 2 6 3 0 1 5] 我得到的是这个
标签的顺序是正确的,但刻度线不正确。标签应该独立地显示正确的元素,而与刻度设置的位置无关。那么错在哪里呢?

请您参考如下方法:

我认为您想要做的是在新图上设置标签以显示值的重新排列顺序。是对的吗?如果是这样,您希望保持标记位置不变,但更改标签:

plt.xticks(np.arange(0,10), neworder) 
plt.yticks(np.arange(0,10), neworder) 

编辑:请注意,这些命令必须在 matshow 之后发出。这似乎是 matshow 的一个怪癖(例如,plot 不显示此行为)。可能与 plt.matshow 文档中的这一行有关:

Because of how :func:matshow tries to set the figure aspect ratio to be the one of the array, if you provide the number of an already existing figure, strange things may happen.

也许最安全的方法是发出 plt.matshow(D) 而不是先创建图形,然后使用 plt.xticks 和 plt.yticks 进行调整。

您的问题还询问了 set_ticks 和相关的 axis 方法。使用这些工具也可以完成同样的事情,在发出 matshow 之后:

ax = plt.gca() 
ax.xaxis.set_ticks(np.arange(0,10))  # turn on all tick locations 
ax.xaxis.set_ticklabels(neworder)    # use neworder for labels 

Edit2:您问题的下一部分与设置最大刻度数有关。 20 需要一个新的例子。对于我们的示例,我将设置最大编号。 2 点的报价:

ax = plt.gca() 
ax.xaxis.set_major_locator(plt.MaxNLocator(nbins=3))  # one less tick than 'bin' 
tl = ax.xaxis.get_ticklocs()                          # get current tick locations 
tl[1:-1] = [neworder[idx] for idx in tl[1:-1]]        # find what the labels should be at those locs 
ax.xaxis.set_ticklabels(tl)                           # set the labels 
plt.draw()