Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

draw grid lines over an image in matplotlib

How can I draw regular grid lines over a tiff image? I want to draw regular square grids for each interval (say 100 by 100 pixels) over the image and save that with the drawings. I also need to overlay each grid id as '1','2',...at the middle of each grid box.

like image 232
2964502 Avatar asked Dec 04 '13 06:12

2964502


2 Answers

You will need the python imaging library (PIL) installed. (See here https://pypi.python.org/pypi/PIL). See these answers for examples of ways to install PIL: answer 1, answer 2

Right, with that installed, the following code should do what you ask for:

import matplotlib.pyplot as plt
import matplotlib.ticker as plticker
try:
    from PIL import Image
except ImportError:
    import Image

# Open image file
image = Image.open('myImage.tiff')
my_dpi=300.

# Set up figure
fig=plt.figure(figsize=(float(image.size[0])/my_dpi,float(image.size[1])/my_dpi),dpi=my_dpi)
ax=fig.add_subplot(111)

# Remove whitespace from around the image
fig.subplots_adjust(left=0,right=1,bottom=0,top=1)

# Set the gridding interval: here we use the major tick interval
myInterval=100.
loc = plticker.MultipleLocator(base=myInterval)
ax.xaxis.set_major_locator(loc)
ax.yaxis.set_major_locator(loc)

# Add the grid
ax.grid(which='major', axis='both', linestyle='-')

# Add the image
ax.imshow(image)

# Find number of gridsquares in x and y direction
nx=abs(int(float(ax.get_xlim()[1]-ax.get_xlim()[0])/float(myInterval)))
ny=abs(int(float(ax.get_ylim()[1]-ax.get_ylim()[0])/float(myInterval)))

# Add some labels to the gridsquares
for j in range(ny):
    y=myInterval/2+j*myInterval
    for i in range(nx):
        x=myInterval/2.+float(i)*myInterval
        ax.text(x,y,'{:d}'.format(i+j*nx),color='w',ha='center',va='center')

# Save the figure
fig.savefig('myImageGrid.tiff',dpi=my_dpi)

Which, if used on the grace_hopper.png example file, produces the following output:

Image with numbered grid

like image 147
tmdavison Avatar answered Oct 25 '22 05:10

tmdavison


This can be done effectively in two lines by looping over the image data at your grid intervals. Using the canonical image from the SIPI database as an example

import pylab as plt

# Load the image
img = plt.imread("lena512color.tiff")

# Grid lines at these intervals (in pixels)
# dx and dy can be different
dx, dy = 100,100

# Custom (rgb) grid color
grid_color = [0,0,0]

# Modify the image to include the grid
img[:,::dy,:] = grid_color
img[::dx,:,:] = grid_color

# Show the result
plt.imshow(img)
plt.show()

enter image description here

The answer by @tom may be more robust as it works with the matplotlib library. I'll leave this example up for its simplicity.

like image 45
Hooked Avatar answered Oct 25 '22 04:10

Hooked