24

I have NumPy arrays which hold circle centers.

import matplotlib.pylab as plt
import numpy as np
npX = np.asarray(X)
npY = np.asarray(Y)
plt.imshow(img)
// TO-DO
plt.show()

How can I show circles at the given positions on my image?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
orkan
  • 512
  • 1
  • 4
  • 18
  • 2
    Possible duplicate of [plot a circle with pyplot](http://stackoverflow.com/questions/9215658/plot-a-circle-with-pyplot) – MB-F Jan 20 '16 at 14:24
  • Quite so. Answers to that question show how to draw circles, which is exactly what you asked for :) – MB-F Jan 20 '16 at 14:28
  • 1
    If you want to draw circles directly onto a numpy array, you can use the Python Imaging Library. See my answer at http://stackoverflow.com/questions/12638790/drawing-a-rectangle-inside-a-2d-numpy-array; change `draw.polygon(...)` to `draw.ellipse(...)`. See the PIL docs for details: http://effbot.org/imagingbook/imagedraw.htm – Warren Weckesser Jan 20 '16 at 14:55

2 Answers2

40

You can do this with the matplotlib.patches.Circle patch.

For your example, we need to loop through the X and Y arrays, and then create a circle patch for each coordinate.

Here's an example placing circles on top of an image (from the matplotlib.cbook)

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Circle

# Get an example image
import matplotlib.cbook as cbook
image_file = cbook.get_sample_data('grace_hopper.png')
img = plt.imread(image_file)

# Make some example data
x = np.random.rand(5)*img.shape[1]
y = np.random.rand(5)*img.shape[0]

# Create a figure. Equal aspect so circles look circular
fig,ax = plt.subplots(1)
ax.set_aspect('equal')

# Show the image
ax.imshow(img)

# Now, loop through coord arrays, and create a circle at each x,y pair
for xx,yy in zip(x,y):
    circ = Circle((xx,yy),50)
    ax.add_patch(circ)

# Show the image
plt.show()

enter image description here

tmdavison
  • 64,360
  • 12
  • 187
  • 165
1

To get the image, instead of plt.show do (Without saving to disc one can get it as):

io_buf = io.BytesIO()
fig.savefig(io_buf, format='raw')#dpi=36)#DPI)
io_buf.seek(0)
img_arr = np.reshape(np.frombuffer(io_buf.getvalue(), dtype=np.uint8),
                         newshape=(int(fig.bbox.bounds[3]), int(fig.bbox.bounds[2]), -1))
io_buf.close()
plt.close()  #To not display the image
user1953366
  • 1,341
  • 2
  • 17
  • 27