Waleed Abdulla
Waleed Abdulla

Reputation: 1941

Removing matplotlib margins

I want to draw a box on an image at location (0, 0). But matplotlib adds a margin such that the box doesn't touch the edge of the image. Here is my code, notice I'm adding a fake image of all zeros and then drawing the box over it.

import matplotlib.pyplot as plt
import matplotlib.patches as patches

fig, ax = plt.subplots(1)
ax.axis('off')
ax.imshow(np.zeros((100, 100)))
p = patches.Rectangle((0, 0), 50, 50, edgecolor='yellow')
ax.add_patch(p)

And this is the output I get. Notice the thin margin at the top and left sides. I tried every suggestion I could find on StackOverflow but nothing worked.

enter image description here

Upvotes: 2

Views: 525

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339765

In order to see, what's happening, let's move a bit closer and not turn the axes off

import matplotlib.pyplot as plt
import matplotlib.patches as patches
import numpy as np; np.random.seed(0)

fig, ax = plt.subplots(1)
#ax.axis('off')
ax.imshow(np.random.rand(7, 7))
p = patches.Rectangle((0, 0), 5, 5, edgecolor='yellow', alpha=0.7)
ax.add_patch(p)

plt.show()

enter image description here

As can be seen, the Rectangle is indeed placed at (0,0). However the axes limits of an imshow plot by default start at (-0.5,-0.5). The reason is that the middle of the pixel is by default considered as the pixel position.

It now depends on what you intend to do. You may either

  1. place the rectangle at (-0.5,-0.5)
  2. Let the image scaling start at (0,0) by either

    • setting the axes limtis plt.xlim(0,n) same for y. (This will crop half a pixel)
    • setting the imshow extent plt.imshow(arr, extent=[0,n,0,n])

Upvotes: 3

Related Questions