Reputation: 25362
Context: I have an image which shows 3 CCDs with a bunch of X-ray interactions shown as bright pixels. I have plotted this data as a histogram (slicing the data to isolate each individual CCD).
I get a histogram which looks like this :
The big peak on the left is the background noise (the actual peak of this goes up further but I changed the axis range to show the other parts of the histogram) and there should be a much smaller peak on the right hand side (though there isn't really one visible on this image) which are the x-ray interactions.
My specific question.. Is there a way to obtain the standard deviation and mean of each peak? Ideally (and I'm not sure if this is actually possible in python) to say, click on both sides of the peak and to calculate the standard deviation and mean of the data within the two clicks?
I'm using python 3.4 and matplotlib version 1.4.3
My code is below:
### read the data ###
a = np.fromfile(filename.img, dtype=np.uint32) #unpack the data and put it into a numpy array
image_data = np.reshape(a[3:], (-1,Cols))
### plotting the data ###
fig, ax = plt.subplots()
ax.imshow(image_data, cmap=cm.gray, interpolation='nearest', clim=(0,2000))
numrows, numcols = image_data.shape
def format_coord(x, y):
x = int(x +0.5)
y = int(y +0.5)
col = x
row = y
if col >= 0 and col < numcols and row >= 0 and row < numrows:
z = image_data[row, col]
return 'x=%1.0f, y=%1.0f, z=%1.0f' % (x, y, z)
else:
return 'x=%1.4f, y=%1.4f' % (x, y)
ax.format_coord = format_coord
plt.figure()
### Obtaining a histogram ###
which_CCD = int(input ('Which CCD? 1,2,3... '))
if which_CCD == 1:
CCD1_image = np.array(image_data[150:1500,300:1498])
CCD1_data=np.reshape(CCD1_image,np.product(CCD1_image.shape))
plt.hist(CCD1_data, bins = 2500, histtype='step')
plt.xlabel('Energy(ADC Channels)')
plt.title('CCD1 Histogram')
plt.figure()
elif which_CCD == 2:
CCD2_image = np.array(image_data[1800:3150,300:1498])
CCD2_data=np.reshape(CCD2_image,np.product(CCD2_image.shape))
plt.hist(CCD2_data, bins = 2500, histtype='step')
plt.xlabel('Energy(ADC Channels)')
plt.title('CCD2 Histogram', fontsize=12)
plt.figure()
elif which_CCD == 3:
CCD3_image = np.array(image_data[150:1500,1948:3146])
CCD3_data=np.reshape(CCD3_image,np.product(CCD3_image.shape))
plt.hist(CCD3_data, bins = 2500, histtype='step')
plt.xlabel('Energy(ADC Channels)')
plt.title('CCD3 Histogram')
plt.figure()
plt.show()
Upvotes: 1
Views: 3447
Reputation: 4290
If I understood you correctly, you want to select a range of X values and calculate mean and std of the Y values in this range.
Here is a simple example of how you can do it. I am sure you can easily adapt it for your needs.
import matplotlib.pyplot as plt
import numpy as np
import numpy.random as npr
# generate random data
data = npr.randn(300)
# calculate hist
heights,edges = np.histogram(data,50)
# center edges
edges = edges[:-1]+(edges[1]-edges[0])
# plot histogram
fig, ax = plt.subplots()
ax.plot(edges,heights)
ax.set(title='Click Twice', xlabel='X', ylabel='Y')
# get input from 2 clicks on figure
point1, point2 = fig.ginput(2)
# paint selected area in red
ax.axvspan(point1[0], point2[0], color='red', alpha=0.5)
# calculate which values are selected and display mean and std
mask = (edges>point1[0]) & (edges<point2[0])
fig.text(0.2,0.83,'Mean: ' + str(np.mean(heights[mask])))
fig.text(0.2,0.8,'Std: ' + str(np.std(heights[mask])))
fig.canvas.draw()
plt.show()
Output:
Histogram with prompt to select points
Paint selected area and display mean and std
P.S. I used this response.
P.P.S. I am on Python 2.7, some syntax changes might be needed for Python 3.
Upvotes: 2