为什么它通过(y,x)而不是(x,y)到ax.annotate?

时间:2018-03-02 22:25:10

标签: python matplotlib

以下代码可视化图像,以灰度显示每个像素的值。

from keras.datasets import mnist

(X_train, y_train), (X_test, y_test) = mnist.load_data()

def visualize_image(img):
    fig, ax = plt.subplots(figsize=(12, 12))
    ax.imshow(img, cmap='gray')
    thresh = img.max()/2.5
    width, height = img.shape
    for x in range(width):
        for y in range(height):
            ax.annotate(str(round(img[x][y])), xy=(y, x), 
                        horizontalalignment='center', 
                        verticalalignment='center,', 
                        color='white' if img[x][y]<thresh else 'black')

visualize_image(X_train[0])

我感到困惑的是它将(y, x)而不是(x, y)传递给ax.annotate的原因?我知道传递(x, y)作为参数会导致错误的图像,但为什么呢?该文件说

  

xy:iterable

     

长度2序列指定要注释的(x,y)点

1 个答案:

答案 0 :(得分:1)

注释功能正常,文档也正确,xy = (x,y)表示x是水平组件,y是垂直组件。这与全世界通常的绘图和图表命名一致。

此处,问题来自于您指定图像width的高度和图像height的宽度。这令人困惑。但当然,用户有责任跟踪变量名称。因此,如果您将宽度heighty命名为通常的x坐标,则需要调用xy = (y,x)

我仍然建议坚持通常的命名约定,因此

def visualize_image(img):
    fig, ax = plt.subplots(figsize=(12, 12))
    ax.imshow(img, cmap='gray')
    thresh = img.max()/2.5
    height, width = img.shape
    for x in range(width):
        for y in range(height):
            ax.annotate(str(round(img[y][x])), xy=(x, y), 
                        horizontalalignment='center', 
                        verticalalignment='center,', 
                        color='white' if img[y][x]<thresh else 'black')