Matplotlib:在刻度之间移动刻度标签 [英] Matplotlib: Move ticklabels between ticks

查看:47
本文介绍了Matplotlib:在刻度之间移动刻度标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to create a visualization of a confusion matrix using matplotlib. Parameters to the methods shown below are the class labels (alphabet), the classification results as a list of lists (conf_arr) and an output filename. I am pretty happy with the result so far, with one last problem:

我无法使网格线之间的轴刻度标签居中.如果我按照以下方式将扩展参数传递给imshow方法,网格按照我希望的方式对齐.如果我将其注释掉,则网格未对齐,但标签是我想要的他们是.我想我需要一种方法来在关联的刻度和下一个刻度之间移动刻度标签但我不知道这是否以及如何可能.

I am not able to center the axis tick labels between the gridlines. If I pass the extent parameter to the imshow method as below, the grid is aligned as I would like it to be. If I comment it out, the grid is missaligned but the labels are were I would like them to be. I think I need a way to move the ticklabel between the associated tick and the next tick but I do not know if and how this is possible.

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

To summarize, I want the grid/ticks like in the left image, but the ticklabels positioned like in the right image:

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')

生成的图像如下所示:

The produced image looks like this:

推荐答案

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

As you've noticed, they're centered by default and you're overriding the default behavior by specifying extent=[0, width, height, 0].

有很多方法可以解决这个问题.一种是使用 pcolor 并设置edgecolors和线型使其看起来像网格线(您实际上需要 pcolor 而不是 pcolormesh 才能工作).但是,您必须更改范围,以使 imshow 默认情况下位于中间的刻度线.

There are a number of ways to handle this. One is to use pcolor and set the edgecolors and linestyles to look like the gridlines (you actually need pcolor and not pcolormesh for this to work). However, you'll have to change the extents to get the ticks in the center as imshow does by default.

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 会更有意义:

Alternatively, you could turn on the minor grid and place it at the pixel boundaries. Because you want fixed labels, we'll just set everything manually. Otherwise, a MultipleLocator would make more sense:

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()

这篇关于Matplotlib:在刻度之间移动刻度标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆