在 matplotlib 中的负坐标上绘制坐标轴艺术家

Plot an axes artist on a negative coordinate in matplotlib

我已经为此苦苦挣扎了一个小时,但仍然感到困惑...我想绘制一系列 15 张图像(热图的每一行一张)并有代码可以这样做:

from matplotlib.offsetbox import OffsetImage, AnnotationBbox

def getImage(path): 
    return OffsetImage(plt.imread(path),zoom=0.085)

for x0, y0, path in zip([0]*15,np.arange(0.5,15.5,1),paths):
    ab = AnnotationBbox(getImage(path), (x0, y0), frameon=False, fontsize=4)
    ax.add_artist(ab)

因为我的 x 坐标是 15 个 0 的列表,所以我的绘图是这样生成的(并非显示所有 15 个徽标):

我想将图像向左移动一点,这样它们就不会与实际的热图重叠,并且可以像文本标签一样很好地对齐。但是,如果我将 x 坐标更改为小于 0 的值(或它出现的轴边界之外的任何值),则会生成绘图,但所有图像都不存在。负坐标不允许加坐标轴艺术家吗?我发现数字 class 有一个 add_artist(),但是当我尝试使用它而不是 ax 时,我得到一个错误:

AttributeError: 'NoneType' object has no attribute 'transData'

所以,有谁知道我如何使用 ax.add_artist() 将这些徽标稍微向左绘制?

编辑: 在查看已接受答案的代码后,我意识到注释框的 xybox 参数将解决我的问题。因此,以下循环工作正确:

for x0, y0, path in zip([0]*15,np.arange(0.5,15.5,1),paths):
    ab = AnnotationBbox(getImage(path), (x0, y0), xybox=(-.4,y0), frameon=False, fontsize=4)
    ax.add_artist(ab)

但是接受的答案的处理方式也可以正常工作。

我改编了@JohanC 对你的作业的出色回应,你对此发表了评论。他应该是回应的人,但出于尊重我会这样做。将图表的轴与加载图像的对象对齐。根据图形数据将标注框的位置设置为负值。为艺术家添加注释框。热图数据取自,球队标志取自英超。

import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.offsetbox import OffsetImage, AnnotationBbox

vegetables = ["cucumber", "tomato", "lettuce", "asparagus",
              "potato", "wheat", "barley"]
farmers = ["Farmer Joe", "Upland Bros.", "Smith Gardening",
           "Agrifun", "Organiculture", "BioGoods Ltd.", "Cornylee Corp."]

teams = ['manchester-city','liverpool','chelsea','arsenal','manchester-united',
         'west-ham-united','tottenham-hotspur-fc']

harvest = np.array([[0.8, 2.4, 2.5, 3.9, 0.0, 4.0, 0.0],
                    [2.4, 0.0, 4.0, 1.0, 2.7, 0.0, 0.0],
                    [1.1, 2.4, 0.8, 4.3, 1.9, 4.4, 0.0],
                    [0.6, 0.0, 0.3, 0.0, 3.1, 0.0, 0.0],
                    [0.7, 1.7, 0.6, 2.6, 2.2, 6.2, 0.0],
                    [1.3, 1.2, 0.0, 0.0, 0.0, 3.2, 5.1],
                    [0.1, 2.0, 0.0, 1.4, 0.0, 1.9, 6.3]])

def add_image(x, y, teams, ax):
    print('./data/premier_logos/{}-logo-vector.png'.format(teams))
    img = plt.imread('./data/premier_logos/{}-logo-vector.png'.format(teams))
    im = OffsetImage(img, zoom=0.085)
    im.image.axes = ax
    x_offset = -25
    ab = AnnotationBbox(im, (x,y), xybox=(x_offset,0), frameon=False, 
                        xycoords='data', boxcoords='offset points', pad=0)
    ax.add_artist(ab)
    
fig, ax = plt.subplots()
im = ax.imshow(harvest)

# Show all ticks and label them with the respective list entries
ax.set_xticks(np.arange(len(farmers)), labels=farmers)
ax.set_yticks(np.arange(len(vegetables)), labels='')

# Rotate the tick labels and set their alignment.
plt.setp(ax.get_xticklabels(), rotation=45, ha="right",
         rotation_mode="anchor")

# Loop over data dimensions and create text annotations.
for i in range(len(vegetables)):
    for j in range(len(farmers)):
        text = ax.text(j, i, harvest[i, j],
                       ha="center", va="center", color="w")

for i,t in enumerate(teams):
    add_image(0, i, t, ax=plt.gca())

ax.set_title("Harvest of local farmers (in tons/year)")
fig.tight_layout()
plt.show()