Adding a grid on top of a tif image in python - matplotlib

Hi I was wondering how to add a grid on top of my image then display it in python.
Here is a picture of what I want to do. NOTE: I also want to specify the line type and color for some of the blocks in the image just like the image below.
Thanks a lot.

The example below shows how to display a .tif file, create a grid, but also how to put the grid below the other plot elements so that you can draw boxes and lines on top of the image and the grid.
import matplotlib.pyplot as plt
from PIL import Image
import matplotlib.patches as mpatches
im = Image.open('stinkbug.tif')
# Flip the .tif file so it plots upright
im1 = im.transpose(Image.FLIP_TOP_BOTTOM)
# Plot the image
plt.imshow(im1)
ax = plt.gca()
# create a grid
ax.grid(True, color='r', linestyle='--', linewidth=2)
# put the grid below other plot elements
ax.set_axisbelow(True)
# Draw a box
xy = 200, 200,
width, height = 100, 100
ax.add_patch(mpatches.Rectangle(xy, width, height, facecolor="none",
edgecolor="blue", linewidth=2))
plt.draw()
plt.show()
You can use matplotlib.patches to draw all types of shapes over your image. To draw individual lines, I like to use the following line, but you can also use matplotlib.lines.Line2D.
plt.axvline(x=0.069, ymin=0, ymax=40, linewidth=4, color='r')

There's imshow function for displaying the image. Displaying the grid on top of the axes is as simple as grid(True).

Related

Save zoomed image at original size wih aditionnal texts and geometries

How to save an image at its original size if this image is displayed zoomed and annoted ?
I have reduced the problem to those lines of code below.
In reality, I have coded an application that offers to annotate a interactive zoomed image and I would like to save the image at its original size with all the different texts and geomtries (annotations) set by the user.
In my example case, I would like to save the original image with the red circle, so fully visible.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
photo = plt.imread("lenna.png")
ax.set_xlim([200,400])
ax.set_ylim([400,200])
ax.imshow(photo)
circle = plt.Circle((400,300), 50, color='red', lw=2, fill=False)
ax.add_artist(circle)
plt.savefig('plot.png')
plt.imsave('save.png', photo)

BoxStyle/FancyBboxPatch/bbox padding ignored by alignment in Matplotlib

I am trying to add a background to a text, and overlay it on a graph. The way I do it is to use the bbox parameter of pyplot.text.
My code:
import matplotlib.pyplot as plt
plt.xlim(0.4,0.6)
plt.ylim(-0.1,0.1)
bbox = dict(facecolor='pink', alpha=0.2, edgecolor='red', boxstyle='square,pad=0.5')
plot,= plt.plot([0.4,0.6],[0,0])
text = plt.text(0.5, 0, 'foo goo', color='gold', size=50, bbox=bbox, horizontalalignment='center', verticalalignment='bottom')
plt.show()
The output:
As you can see, verticalalignment='bottom' considers only the bottom of the text, ignoring the padding of the bbox. Is there any 'native' means to correct this? If not, how should I offset the coordinates correctly to compensate for the padding?
The box has a margin padding of 0.5 times the fontsize of 50 pts. This means you want to offset the text 25 points from a position in data coordinates.
Fortunately, using an Annotation instead of Text allows to do exactly that. Creating an Annotation can be done via .annotate, which takes a xytext and a textcoords argument for exactly such purpose.
import matplotlib.pyplot as plt
plt.xlim(0.4,0.6)
plt.ylim(-0.1,0.1)
bbox = dict(facecolor='pink', alpha=0.2, edgecolor='red', boxstyle='square,pad=0.5')
plot,= plt.plot([0.4,0.6],[0,0])
text = plt.annotate('foo goo', xy=(0.5, 0), xytext=(0,0.5*50), textcoords="offset points",
color='gold', size=50, bbox=bbox, ha='center', va='bottom')
plt.show()

plot several image files in matplotlib subplots

I would like to create a matrix subplot and display each BMP files, from a directory, in a different subplot, but I cannot find the appropriate solution for my problem, could somebody helping me?.
This the code that I have:
import os, sys
from PIL import Image
import matplotlib.pyplot as plt
from glob import glob
bmps = glob('*trace*.bmp')
fig, axes = plt.subplots(3, 3)
for arch in bmps:
i = Image.open(arch)
iar = np.array(i)
for i in range(3):
for j in range(3):
axes[i, j].plot(iar)
plt.subplots_adjust(wspace=0, hspace=0)
plt.show()
I am having the following error after executing:
natively matplotlib only supports PNG images, see http://matplotlib.org/users/image_tutorial.html
then the way is always read the image - plot the image
read image
img1 = mpimg.imread('stinkbug1.png')
img2 = mpimg.imread('stinkbug2.png')
plot image (2 subplots)
plt.figure(1)
plt.subplot(211)
plt.imshow(img1)
plt.subplot(212)
plt.imshow(img2)
plt.show()
follow the tutorial on http://matplotlib.org/users/image_tutorial.html (because of the import libraries)
here is a thread on plotting bmps with matplotlib: Why bmp image displayed as wrong color with plt.imshow of matplotlib on IPython-notebook?
The bmp has three color channels, plus the height and width, giving it a shape of (h,w,3). I believe plotting the image gives you an error because the plot only accepts two dimensions. You could grayscale the image, which would produce a matrix of only two dimensions (h,w).
Without knowing the dimensions of the images, you could do something like this:
for idx, arch in enumerate(bmps):
i = idx % 3 # Get subplot row
j = idx // 3 # Get subplot column
image = Image.open(arch)
iar_shp = np.array(image).shape # Get h,w dimensions
image = image.convert('L') # convert to grayscale
# Load grayscale matrix, reshape to dimensions of color bmp
iar = np.array(image.getdata()).reshape(iar_shp[0], iar_shp[1])
axes[i, j].plot(iar)
plt.subplots_adjust(wspace=0, hspace=0)
plt.show()

matplotlib: how to hide grey border around the plot

I'd like to save figurecanvas as bitmap and don't need grey border around the plot in it. How can I hide this?
I believe that savefig will not include the gray border by default. However, .bmp is not support by savefig; use .png instead.
import pylab
f = pylab.figure()
ax = f.add_axes([0.1, 0.1, 0.8, 0.8])
ax.plot([1,2,3],[4,5,6])
f.savefig('image.png')
Output:
(source: stevetjoa.com)
I found it: subplots_adjust.

matplotlib: Controlling pie chart font color, line width

I'm using some simple matplotlib functions to draw a pie chart:
f = figure(...)
pie(fracs, explode=explode, ...)
However, I couldn't find out how to set a default font color, line color, font size – or pass them to pie(). How is it done?
Showing up a bit late for the party but I encountered this problem and didn't want to alter my rcParams.
You can resize the text for labels or auto-percents by keeping the text returned from creating your pie chart and modifying them appropriately using matplotlib.font_manager.
You can read more about using the matplotlib.font_manager here:
http://matplotlib.sourceforge.net/api/font_manager_api.html
Built in font sizes are listed in the api;
"size: Either an relative value of ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’ or an absolute font size, e.g. 12"
from matplotlib import pyplot as plt
from matplotlib import font_manager as fm
fig = plt.figure(1, figsize=(6,6))
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
plt.title('Raining Hogs and Dogs')
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
fracs = [15,30,45, 10]
patches, texts, autotexts = ax.pie(fracs, labels=labels, autopct='%1.1f%%')
proptease = fm.FontProperties()
proptease.set_size('xx-small')
plt.setp(autotexts, fontproperties=proptease)
plt.setp(texts, fontproperties=proptease)
plt.show()
Global default colors, line widths, sizes etc, can be adjusted with the rcParams dictionary:
import matplotlib
matplotlib.rcParams['text.color'] = 'r'
matplotlib.rcParams['lines.linewidth'] = 2
A complete list of params can be found here.
You could also adjust the line width after you draw your pie chart:
from matplotlib import pyplot as plt
fig = plt.figure(figsize=(8,8))
pieWedgesCollection = plt.pie([10,20,50,20],labels=("one","two","three","four"),colors=("b","g","r","y"))[0] #returns a list of matplotlib.patches.Wedge objects
pieWedgesCollection[0].set_lw(4) #adjust the line width of the first one.
Unfortunately, I can not figure out a way to adjust the font color or size of the pie chart labels from the pie method or the Wedge object. Looking in the source of axes.py (lines 4606 on matplotlib 99.1) they are created using the Axes.text method. This method can take a color and size argument but this is not currently used. Without editing the source, your only option may be to do it globally as described above.
matplotlib.rcParams['font.size'] = 24
does change the pie chart labels font size