1
votes

I’m plotting an image like this

fig, ax = plt.subplots()
ax.imshow(im, cmap = "gray")

I would like to draw a rectangle on top of the image with the following parameters (in image coordinates)

(0, 0, 240, 210)

(Top, left, width, height)

The docs for a rectangle patch says that the first parameter is a tuple specifying the “bottom left” of the rectangle.

rect = mpatches.Rectangle((0, 0 + 210), 240, 210, fill = False, linewidth = 2, edgecolor = randHex())
ax.add_patch(rect)

After plotting this, the rectangle shows up in the wrong place and I’m not sure why. I think there’s some kind of coordinate system mismatch between image coordinates which I’m using at the matplotlib’s coordinate system.

EDIT: If I just use (0, 0) it works fine, but that’s inconsistent with the docs.

2
@DjaballahDJEDID do you mind saying why? That would be the top right of the rectangle if I’m not mistaken. - Carpetfizz

2 Answers

3
votes

If the axis goes from top to bottom, the bottom of the rectangle is actually the top, seen in data coordinates. However, what is always true is that a rectangle

plt.Rectangle((x, y), w, h)

expands from (x,y) to (x+w, y+h).

So when we plot the same rectangle plt.Rectangle((1,2), 2, 1) in axes with different orientations of the respective x and y axes, it will look different.

import matplotlib.pyplot as plt

def plot_rect(ax):
    rect = plt.Rectangle((1,2), 2, 1)
    ax.add_patch(rect)
    ax.scatter([1], [2], s=36, color="k", zorder=3)


fig, axs = plt.subplots(2,2)

xlims = ((-4,4), (-4,4), (4,-4), (4,-4))
ylims = ((-4,4), (4,-4), (-4,4), (4,-4))

for ax, xlim, ylim in zip(axs.flat, xlims, ylims):
    plot_rect(ax)
    ax.set(xlim=xlim, ylim=ylim)

plt.show()

enter image description here

0
votes

I guess you read the wrong doc! Haha Well, the coordinates start from the top left corner of the rectangle.

(x, y, w, h)

(x, y) are the top left corners, where (w, y) are the width and height of the rectangle.

Hope it helps. Peace out.