Plotting image Red channel by intensity - python

Okay, So i'm trying to take the red channel of an image, and plot it (preferably 3d) to an image. The image is 480x640 (or thereabouts), and is taken from a webcam. I'm currently using scipy, numpy, and python to get the image, extract he red channel, and process it. That all works.
However, when i try to plot it, 2 different problems occur, depending on how I try to plot:
1) Width mismatch, it doesn't like that the image isn't square.
2) It only plots one row of the image (x val = 0, all y vals).
I've attached the relevent code. Comments are everywhere, for when i try different ways.
fig = plt.figure()
#ax = Axes3D(fig)
#ax = fig.add_subplot(111, projection='3d')
X = [range(480), range(480)]
Y = [range(480), range(480)]
#X = range(len(self.R))
#Y = range(len(self.R))
'''
surf = ax.plot_surface(X, Y, np.resize(self.R, (480, 480)) , rstride=1, cstride=10, cmap=cm.jet, linewidth=0, antialiased=False)
ax.set_zlim3d(0.0, 255.0)
ax.w_zaxis.set_major_locator(LinearLocator(100))
ax.w_zaxis.set_major_formatter(FormatStrFormatter('%.03f'))
m = cm.ScalarMappable(cmap=cm.jet)
m.set_array(self.frame_in)
fig.colorbar(m)
np.savetxt("tmp.txt", self.R)
'''
#np.savetxt("tmp.out", self.R[0])
#np.savetxt("tmp.out1", self.R[1])
#np.savetxt("tmp.txt", self.frame_in, "[ %s ]", "\t")
#plt.subplot(212)
#x, y = self.R.shape
#x = range(x)
#y = range(y)
#X, Y = np.meshgrid(x, y)
plt.scatter(X, Y, self.R)
#plt.pcolormesh(self.R)
#plt.colorbar()
#ax.scatter(x, y, self.R, c='r', marker='o')
plt.show()
I can clean up the code if needed, but i wanted everyone to see the multiple ways i've tried. Am i missing something really stupid simple? It doesn't make sense that it will work with the first row, and not all of them.
Thanks in advance!

Try using pyplot.imshow:
plt.cmap('Reds')
plt.imshow(self.R)
plt.show()

Related

Scipy.interpolate and a 3D surface in matplotlib - data seems to be rotated within the axes?

I'm having trouble understanding a strange side effect of interpolating my data. I am plotting a 2D surface onto a 3D grid, this part works fine, however as soon as I tweaked it to include scipy.interpolate I get a strange glitch, (at least I think it is a glitch).
Below is an image of two plots, LHS is the original data, RHS the interpolated plot. As you can see I have rotated the RHS so that the similarities between the shapes are clear, but as a result the axis facing us is different;
(I have rotated both of these extensively and I'm confident the symmetry in this view is not a coincidence, it looks too similar and they look too different when viewed at the same rotation)
To add interpolation to my code I followed the answer to this question:
Smooth surface Plot with Pyplot
I'll also add my code before and after I added that bit, in the hope that there's something really obvious I've missed
ax = fig.add_subplot(111, projection='3d')
#y is the sin(beta-alpha) value, x is the tan(beta) value and z is the cross-section in fb
y = np.array(Y_list)
x = np.array(x_list)
X, Y = np.meshgrid(x, y)
zs = np.array(z_list)
Z = zs.reshape(Y.shape)
print(type(Z))
print(Z.shape)
ax.plot_surface(X, Y, Z)
plt.ylabel(r"$Sin(\beta - \alpha)$")
plt.xlabel(r"$Tan(\beta)$")
ax.zaxis.set_rotate_label(False) # disable automatic rotation
ax.set_zlabel('Cross-section (pb)', rotation=90)
#this is the rotation bit
for angle in range(0, 360):
ax.view_init(30, angle)
plt.draw()
plt.pause(.001)
(Obviously there is code beforehand importing everything such as numpy, scipy etc and getting the data, but this is untouched between the two versions)
y = np.array(Y_list)
x = np.array(x_list)
xstart = float(x[0])
xend = float(x[-1])
ystart = float(y[0])
yend = float(y[-1])
X, Y = np.mgrid[xstart:xend:10j, ystart:yend:22j]
zs = np.array(z_list)
#Z = zs.reshape(Y.shape)
#The following lines perform interpolation
tck = interpolate.bisplrep(X, Y, zs, s=0)
Znew = interpolate.bisplev(X[:,0], Y[0,:], tck)
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_surface(X, Y, Z)
plt.ylabel(r"$Sin(\beta - \alpha)$")
plt.xlabel(r"$Tan(\beta)$")
ax.zaxis.set_rotate_label(False) # disable automatic rotation
ax.set_zlabel('Cross-section (pb)', rotation=90)
#this is the rotation bit
for angle in range(0, 360):
ax.view_init(30, angle)
plt.draw()
plt.pause(.001)
I'm stumped and any help would be appreciated!

plot a cylinder in python

I am trying to plot a full cylinder, using a cylindrical mesh grid.
However I just managed to get half a cylinder. Here is my code
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
r = 1
x = np.linspace(-r, r, 50)
y = np.linspace(-r, r, 50)
X, Y = np.meshgrid(x, y)
Z = (np.pi * -Y**2)
surf = ax.plot_surface(X, Y, Z)
What I would like to obtain is something like this
Could anybody give me some insights on how to do it?
In this post the ax.plot_surface function is called twice. In your case adding a minus sign to the Z does not yet result in a cylinder, but at least you have a top and bottom part.

Crop plot 1 according to the shape of plot 2

I'm trying to plot a heatmap with the plt.pcolormesh, and then plot the outline of my figure with the plt.scatter and I would like to crop the result according to the shape of the last plot which is the outline.
It doesn't seem that hard to do but still I haven't managed to do it or found anything. Here is my code and an image to illustrate, thank you for your help!
plt.rcParams["figure.figsize"] = (10.0, 10.0)
plt.axis("off")
plt.pcolormesh(x, y, intens)
plt.colorbar()
coord = np.genfromtxt("myfile.csv", delimiter = ' ')
x = [coord[i][0] for i in range(0, len(coord))]
y = [coord[i][1] for i in range(0, len(coord))]
plt.scatter(x, y, c = 'k', s = 1.)
Image here
You can just use plt.xlim() and plt.ylim() and give them the coordinates of the new figure. Here is a modified version of the code:
plt.rcParams['figure.figsize'] = (10.0, 10.0)
plt.axis('off')
plt.pcolormesh(x, y, intens)
plt.colorbar()
coord = np.genfromtxt('myfile.csv', delimiter=' ')
x = coord[:, 0]
y = coord[:, 1]
plt.scatter(x, y, c='k', s=1.)
plt.xlim([np.min(x), np.max(x)])
plt.ylim([np.min(y), np.max(y)])

Plot 3D Contour from an Image using extent with Matplotlib

As I present here (in 2D), I'm wondering if how I could "scale" an image input to be plotted to a range in the plot. To be more clear, this is what I need:
I have a 400 * 400 image that is generated based on a function which interval is -1..1. So, I do a translate to save this data, like this:
x = Utils.translate(pos_x, 0, self.width, -1, 1)
y = Utils.translate(pos_y, 0, self.height, -1, 1)
data = Utils.map_position_to_function(x, y)
I.e, first I map its position to my range and then I calculate de f(x, y) based on this "new position" and save the data. Also, as I save this image, I do a translate in data so it fits in a 0..255 range, generating a grayscale image.
The problem is that, later, I have to represent the image contour in the function range. So, I have an image, 400 * 400, that I have to represent in a plot which range is -1..1.
In 2D, I could do this with this code:
im = plt.array(Image.open('Mean.png').convert('L'))
plt.figure()
CS = plt.contour(im, origin='image', extent=[-1, 1, -1, 1])
plt.clabel(CS, inline=1, fontsize=10)
plt.savefig("CountorLevel2D.png")
In 3D, I tried this:
fig = plt.figure()
ax = fig.gca(projection='3d')
row = np.linspace(0, 400, 400)
X,Y = np.meshgrid(row,row)
CS = ax.contour(X, Y, im, cmap=cm.coolwarm, extent=[-1, 1, -1, 1])
plt.clabel(CS, inline=1, fontsize=10)
plt.savefig("ContourLevel3D.png")
But the X and Y are still in the 0..400 range. I don't know what is wrong, or what I have to do to have X and Y in -1..1 range. Besides, no label is shown.
Also, as im is an image, I read values which ranges between 0..255 values. How could I present this in an -1..1 range too?
Thanks in advance. (:
Try this insted:
fig = plt.figure()
ax = fig.gca(projection='3d')
row = np.linspace(-1, 1, 400)
X,Y = np.meshgrid(row,row)
CS = ax.contour(X, Y, im, cmap=cm.coolwarm)
plt.clabel(CS, inline=1, fontsize=10)
plt.savefig("ContourLevel3D.png")

Grid Lines below the contour in Matplotlib

I have one question about the grid lines matplotlib.
I am not sure if this is possible to do or not.
I am plotting the following graph as shown in the image.
I won't give the entire code, since it is involving reading of files.
However the important part of code is here -
X, Y = np.meshgrid(smallX, smallY)
Z = np.zeros((len(X),len(X[0])))
plt.contourf(X, Y, Z, levels, cmap=cm.gray_r, zorder = 1)
plt.colorbar()
...
# Set Border width zero
[i.set_linewidth(0) for i in ax.spines.itervalues()]
gridLineWidth=0.1
ax.set_axisbelow(False)
gridlines = ax.get_xgridlines()+ax.get_ygridlines()
#ax.set_axisbelow(True)
plt.setp(gridlines, 'zorder', 5)
ax.yaxis.grid(True, linewidth=gridLineWidth, linestyle='-', color='0.6')
ax.xaxis.grid(False)
ax.xaxis.set_ticks_position('none')
ax.yaxis.set_ticks_position('none')
Now, my questions is like this -
If I put the grid lines below the contour, they disappear since they are below it.
If I put the grid line above the contour, they looks like what they are looking now.
However, what I would like to have is the grid lines should be visible, but should be below the black portion of the contour. I am not sure if that is possible.
Thank You !
In addition to specifying the z-order of the contours and the gridlines, you could also try masking the zero values of your contoured data.
Here's a small example:
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(-2*np.pi, 2*np.pi, 0.1)
y = np.arange(-2*np.pi, 2*np.pi, 0.1)
X, Y = np.meshgrid(x, y)
Z = np.sin(X) - np.cos(Y)
Z = np.ma.masked_less(Z, 0) # you use mask_equal(yourData, yourMagicValue)
fig, ax = plt.subplots()
ax.contourf(Z, zorder=5, cmap=plt.cm.coolwarm)
ax.xaxis.grid(True, zorder=0)
ax.yaxis.grid(True, zorder=0)
And the output:

Categories

Resources