I need to plot over an image. I use this code to display the image:
plt.figure()
mngr = plt.get_current_fig_manager()
fname = 'erausal-valence.jpg'
image = Image.open(fname).convert("L")
arr = np.asarray(image)
plt.imshow(arr)
Over on this image I need to plot an array build with components:
for i in range(0, len(BPM)):
for k in range(0, len(BPM)):
(X[k], Y[k]) = pol2cart(BPM[k], -SC[k]);
plt.plot(X[k], Y[k])
but plot shows the image and doesn't show the plot of the X and Y arrays.
What are the values of X and Y? I've used the code below and could plot a graph over an image.
import matplotlib.pyplot as plt
import matplotlib.cbook as cbook
imageFile = cbook.get_sample_data('ada.png')
image = plt.imread(imageFile)
plt.imshow(image)
coords = [0, 100, 200, 300, 400, 500, 600]
plt.plot(coords, coords, 'r--', linewidth=2)
plt.show()
To add the background image, you have to add this import :
from matplotlib import cbook
And now to fill it in the background you should add these lines before the show instruction:
imageFile = cbook.get_sample_data('<Path_to_your_image>')
image = plt.imread(imageFile)
plt.imshow(image)
Related
I have some microscopic images where there are precipitates in single states and in some we have in horizontal or vertical lines. Now how should I remove these lines?
import matplotlib.pyplot as plt
import numpy as np
from scipy import ndimage as ndi
import cv2
import math
from skimage import (
color, feature, filters, measure, morphology, segmentation, util
)
# Sample1 - T61
image = cv2.imread(r"C:\Users\Stelle1.tif",cv2.IMREAD_GRAYSCALE)
assert not isinstance(image,type(None)), 'image not found'
fig, ax = plt.subplots()
ax.imshow(image, cmap='gray')
ax.axis('off')
plt.imshow()
click to view the image
fig, ax = plt.subplots(figsize=(5, 5))
qcs = ax.contour(image, origin='image')
ax.axis('off')
plt.show()
thresholds = filters.threshold_multiotsu(image, classes=3)
regions = np.digitize(image, bins=thresholds)
fig, ax = plt.subplots(ncols=2, figsize=(10, 5))
ax[0].imshow(image)
ax[0].set_title('Original')
ax[0].axis('off')
ax[1].imshow(regions)
ax[1].set_title('Multi-Otsu thresholding')
ax[1].axis('off')
plt.show()
cells = image > thresholds[0]
dividing = image > thresholds[1]
labeled_cells = measure.label(cells)
labeled_dividing = measure.label(dividing)
naive_mi = labeled_dividing.max() / labeled_cells.max()
print(naive_mi)
higher_threshold = 100
dividing = image > higher_threshold
smoother_dividing = filters.rank.mean(util.img_as_ubyte(dividing),
morphology.disk(4))
binary_smoother_dividing = smoother_dividing > 20
fig, ax = plt.subplots(figsize=(5, 5))
ax.imshow(binary_smoother_dividing)
ax.set_title('Dividing precipitate')
ax.axis('off')
plt.show()
click to view the image
Here is what I got if I increase the higher_threshold = 100, I will lose the ellipse shape precipitate where I need to count the area and other properties. Can you suggest some solution that the algorithm should not detect the line shape precipitates?
Have you thought about using something like a hough transform to detect straight lines?:
https://scikit-image.org/docs/dev/auto_examples/edges/plot_line_hough_transform.html
I basically lifted this straight from the above tutorial and got some pretty decent out of the box results.
from skimage import io
from skimage.transform import probabilistic_hough_line
from skimage.feature import canny
img = io.imread('GsSj9.png', as_gray=True) # read in the image
edges = canny(img) # use canny filter to detect edges
lines = probabilistic_hough_line(edges, threshold=20, line_length=20, line_gap=3)
# make plot of image and probabilistic_hough_line
fig, axes = plt.subplots(1, 2, sharex=True, sharey=True)
ax = axes.ravel()
ax[0].imshow(img)
ax[0].set_title('image')
ax[1].imshow(img * 0)
for line in lines:
p0, p1 = line
ax[1].plot((p0[0], p1[0]), (p0[1], p1[1]))
ax[1].set_xlim((0, img.shape[1]))
ax[1].set_ylim((img.shape[0], 0))
ax[1].set_title('Probabilistic Hough')
You would still need to figure out a good way to make a binary image from the transform lines but it could be useful in your endeavor.
I have a list of three images' file names, I want to plot them using matplotlib, the attempt I made is below. I tried to plot them all but they are all plotted to the same location so the final image appears on top.
I want to plot the first at location coordinates (0,0), the second at (100,200) and the third at (200,200). I read the documentation on matplotlib.imshow but cannot find how to set the location of the image using the coordinates.
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
imageList = ["foo.jpg", "bar.jpg", "foobar.jpg"]
coordinatesList = [[0,0],[100,200],[200,200]]
for i in range(3):
imageFile = imageList[i]
coordinate = coordinatesList[i]
img=mpimg.imread(imageFile)
imgplot = plt.imshow(img)
I see 2 ways to do this:
with matplotlib.transforms:
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import matplotlib as mpl
imageList = ["image.jpg", "image.jpg", "image.jpg"]
coordinatesList = [[0, 0], [100, 200], [200, 200]]
ax = plt.gca()
ax.set_xlim(0, 300)
ax.set_ylim(0, 300)
for i in range(3):
imageFile = imageList[i]
img=mpimg.imread(imageFile)
imgplot = ax.imshow(img)
tx, ty = coordinatesList[i]
transform = mpl.transforms.Affine2D().translate(tx, ty)
imgplot.set_transform(transform + ax.transData)
plt.show()
with extent option (but I know my image's dimensions):
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
imageList = ["image.jpg", "image.jpg", "image.jpg"]
coordinatesList = [[0, 0], [100, 200], [200, 200]]
ax = plt.gca()
ax.set_xlim(0, 300)
ax.set_ylim(0, 300)
imgplot = [None] * len(imageList)
for i in range(3):
imageFile = imageList[i]
img=mpimg.imread(imageFile)
tx, ty = coordinatesList[i]
ax.imshow(img, extent=(tx, tx + 50, ty, ty + 50))
plt.show()
Here's the result using a 50px square as a picture image.png:
I have an image of shape (271, 300, 3) containing values between 0 and 1 (image/255)
And I would like to put all the pixels of this image in another variable (pixel) with the method reshape, how to do that ? Here is my few code
image = plt.imread('im3.jpg')
im = image/255.0
print(im.shape) #(271, 300, 3)
Until here, I've tried to do that :
pixels = im.reshape(im.shape[0]*im.shape[1]*im.shape[2])
but I don't think it is the way to do that.
To reshape it to flat array with pixels which have three values (R,G,B)
pixels = im.reshape( im.shape[0]*im.shape[1], im.shape[2] )
It will convert (271, 300, 3) to (81300, 3)
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
image = plt.imread('im3.jpg')
im = image/255.0
print(im.shape) #(271, 300, 3)
pixels = im.reshape(im.shape[0]*im.shape[1], im.shape[2])
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(pixels[:,0], pixels[:,1], pixels[:,2], c=pixels)
plt.show()
I have a .png image with alpha channel and a random pattern generated with numpy.
I want to supperpose both images using matplotlib. The bottom image must be the random pattern and over this, I want to see the second image (attached in the end of the post).
The code for both images is the following:
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
# Random image pattern
fig = plt.subplots(figsize = (20,4))
x = np.arange(0,2000,1)
y = np.arange(0,284,1)
X,Y = np.meshgrid(x,y)
Z = 0.6+0.1*np.random.rand(284,2000)
Z[0,0] = 0
Z[1,1] = 1
# Plot the density map using nearest-neighbor interpolation
plt.pcolormesh(X,Y,Z,cmap = cm.gray)
The result is the following image:
To import the image, I use the following code:
# Sample data
fig = plt.subplots(figsize = (20,4))
# Plot the density map using nearest-neighbor interpolation
plt.imread("good_image_2.png")
plt.imshow(img)
print(img.shape)
The image is the following:
Thus, the final result that I want is:
You can make an image-like array for Z and then just use imshow to display it before the image of the buttons, etc. Note that this only works because your png has an alpha channel.
Code:
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
# Plot the density map using nearest-neighbor interpolation
img = plt.imread("image.png")
(xSize, ySize, cSize) = img.shape
x = np.arange(0,xSize,1)
y = np.arange(0,ySize,1)
X,Y = np.meshgrid(x,y)
Z = 0.6+0.1*np.random.rand(xSize,ySize)
Z[0,0] = 0
Z[1,1] = 1
# We need Z to have red, blue and green channels
# For a greyscale image these are all the same
Z=np.repeat(Z,3).reshape(xSize,ySize,3)
fig = plt.figure(figsize=(20,8))
ax = fig.add_subplot(111)
ax.imshow(Z, interpolation=None)
ax.imshow(img, interpolation=None)
fig.savefig('output.png')
Output:
You can also turn off axes if you prefer.
ax.axis('off')
For example, I plot a figure using matplotlib as follows:
plt.figure(figsize=(10,10))
plt.imshow(output_fig, zorder=0,cmap="gray")
plt.scatter(x,y,color='k')
if I use:
plt.savefig(figname,fotmat=figtype)
I will save it as a figure file. However, I want so save it to a matrix, or numpy array, such that each element saves the scale value of each pixel of the figure.
How can I do this?
I find solutions saving the RGB values. But I hope to save a greyscale figure.
Thank you all for helping me!
Once you have a ploted data (self contained example bellow):
import numpy as np
import matplotlib.pyplot as plt
from skimage import data, color
img = data.camera()
x = np.random.rand(100) * img.shape[1]
y = np.random.rand(100) * img.shape[0]
fig = plt.figure(figsize=(10,10))
plt.imshow(img,cmap="gray")
plt.scatter(x, y, color='k')
plt.ylim([img.shape[0], 0])
plt.xlim([0, img.shape[1]])
The underlying data can be recovered as array by using fig.canvas (the matplotlib's canvas). First trigger its drawing:
fig.canvas.draw()
Get the data as array:
width, height = fig.get_size_inches() * fig.get_dpi()
mplimage = np.fromstring(fig.canvas.tostring_rgb(), dtype='uint8').reshape(height, width, 3)
If you want your array to be the same shape as the original image you will have to play with figsize and dpi properties of plt.figure().
Last, matplotlib returns an RGB image, if you want it grayscale:
gray_image = color.rgb2gray(mplimage)