【问题标题】:Matplotlib: Move ticklabels between ticksMatplotlib:在刻度之间移动刻度标签
【发布时间】:2014-08-03 03:49:44
【问题描述】:

我想使用 matplotlib 创建混淆矩阵的可视化。 下面显示的方法的参数是类标签(字母), 分类结果为列表列表 (conf_arr) 和输出文件名。 到目前为止,我对结果感到非常满意,还有最后一个问题:

我无法在网格线之间将轴刻度标签居中。 如果我将 extent 参数传递给 imshow 方法,如下所示, 网格按照我的意愿对齐。 如果我将其注释掉,则网格未对齐,但标签是我想要的 他们是。 我想我需要一种方法来在关联的刻度和下一个刻度之间移动刻度标签 但我不知道这是否以及如何实现。

总而言之,我想要左图中的网格/刻度,但是刻度标签 如右图所示:

def create_confusion_matrix(alphabet, conf_arr, outputname):
    norm_conf = []
    width = len(conf_arr)
    height = len(conf_arr[0])
    for i in conf_arr:
        a = 0
        tmp_arr = []
        a = sum(i, 0)
        for j in i:
            tmp_arr.append(float(j)/float(a))
        norm_conf.append(tmp_arr)

    fig = plt.figure(figsize=(14,14))
    #fig = plt.figure()
    plt.clf()
    ax = fig.add_subplot(111)
    ax.set_aspect(1)
    ax.grid(which='major')
    res = ax.imshow(np.array(norm_conf), cmap=plt.cm.binary, 
                    interpolation='none', aspect='1', vmax=1,
                    ##Commenting out this line sets labels correctly,
                    ##but the grid is off
                    extent=[0, width, height, 0]
                    )
    divider = make_axes_locatable(ax)
    cax = divider.append_axes("right", size="5%", pad=0.2)
    cb = fig.colorbar(res, cax=cax)

    #Axes
    ax.set_xticks(range(width))
    ax.set_xticklabels(alphabet, rotation='vertical')
    ax.xaxis.labelpad = 0.5
    ax.set_yticks(range(height))
    ax.set_yticklabels(alphabet, rotation='horizontal')
    #plt.tight_layout()
    plt.savefig(outputname, format='png')

生成的图像如下所示:

【问题讨论】:

标签: python matplotlib


【解决方案1】:

正如您所注意到的,它们默认居中,您通过指定 extent=[0, width, height, 0] 来覆盖默认行为。

有很多方法可以处理这个问题。一种是使用pcolor 并将边缘颜色和线条样式设置为看起来像网格线(您实际上需要pcolor 而不是pcolormesh 才能工作)。但是,您必须像 imshow 默认那样更改范围以使刻度位于中心。

import matplotlib.pyplot as plt
import numpy as np

data = np.random.random((10,10))
labels = 'abcdefghij'

fig, ax = plt.subplots()
im = ax.pcolor(data, cmap='gray', edgecolor='black', linestyle=':', lw=1)
fig.colorbar(im)

# Shift ticks to be at 0.5, 1.5, etc
for axis in [ax.xaxis, ax.yaxis]:
    axis.set(ticks=np.arange(0.5, len(labels)), ticklabels=labels)

plt.show()

或者,您可以打开小网格并将其放置在像素边界处。因为您需要固定标签,所以我们将手动设置所有内容。否则,MultipleLocator 会更有意义:

import matplotlib.pyplot as plt
import numpy as np

data = np.random.random((10,10))
labels = 'abcdefghij'

fig, ax = plt.subplots()
im = ax.imshow(data, cmap='gray', interpolation='none')
fig.colorbar(im)

# Set the major ticks at the centers and minor tick at the edges
locs = np.arange(len(labels))
for axis in [ax.xaxis, ax.yaxis]:
    axis.set_ticks(locs + 0.5, minor=True)
    axis.set(ticks=locs, ticklabels=labels)

# Turn on the grid for the minor ticks
ax.grid(True, which='minor')

plt.show()

【讨论】:

  • 非常感谢您的努力,完美解决了我的问题! :)
【解决方案2】:

或者:您是否尝试过im = ax.matshow(data, cmap='gray') 而不是imshow()?这也应该将刻度标签放在正确的位置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-21
    • 1970-01-01
    • 2019-07-10
    • 1970-01-01
    • 1970-01-01
    • 2021-09-05
    相关资源
    最近更新 更多