Hi there,
I want to get bounding boxes of all bars in a bar chart in pixels (so I want to get the actual pixel coordinates of the top-left and bottom-right corners of a bar of the rendered image). Does anyone know how I can achieve this? I have some code that gives me some coordinates but when I check the pixels with other tools they are not at all on the corners. It would also be good to know whether axis labels shift these coordinates and where the origin is for matplotlib (I think it’s the bottom left of the image)?
My current code:
plt.bar([1,2,3], [3,4,5])
plt.xlim(0.5, 3.5)
plt.ylim(0, 5.5)
fig = plt.gcf()
fig.canvas.draw() # ax.transData.transform only properly works after the figure is drawn (?)
r = fig.canvas.get_renderer()
fig_width, fig_height = fig.canvas.get_width_height() # get w/h in display (pixel) coordinates
for rect in ax.patches:
print('\n' + str(rect))
point_x, point_y = rect.get_x(), rect.get_y()
h, w = rect.get_height(), rect.get_width()
ax.plot([point_x], [point_y], 'o', color='red')
x1, y1 = ax.transData.transform_point([point_x, point_y])
x2, y2 = ax.transData.transform_point([point_x+w, point_y+h])
# make the top left (0,0)
y1 = fig_height - y1
y2 = fig_height - y2
print(f'{x1=:.0f}, {y1=:.0f}')
print(f'{x2=:.0f}, {y2=:.0f}')
Output:
Rectangle(xy=(0.6, 0), width=0.8, height=3, angle=0)
x1=97, y1=427
x2=229, y2=226
Rectangle(xy=(1.6, 0), width=0.8, height=4, angle=0)
x1=262, y1=427
x2=394, y2=158
Rectangle(xy=(2.6, 0), width=0.8, height=5, angle=0)
x1=427, y1=427
x2=559, y2=91
