Fit of intensity distribution does not work - python

So im sitting here and don't know how to fit the right function for my Intensity distribution of a doubleslit experiment. I tried so much but I don't know how it works. The x,y data are more than 1000 values.
Here is my Plot:
And here's how it should look like:
And that is my code to that:
import matplotlib.patches as mp
import matplotlib.pyplot as plt
import numpy as np
from scipy import optimize
from scipy.optimize import curve_fit
import pandas as pd
import math
data = pd.read_csv('TEM00-Doppelspalt-Short.txt',sep='\s+',header=None)
data = pd.DataFrame(data)
x = data[1]
y = data[2]
def expf(i0,g,k,y0,d):
return i0*((np.sin(g*(k-y0)))/(g*(k-y0)))**2*np.cos(d*(k-y0))**2
popt, pcov =curve_fit(expf, x, y, p0 = (13, 20, 2, 4))
g,k,y0,d = popt
plt.figure(figsize = (8,6), dpi = 600)
plt.xlabel(r'Wavelength [$\mu$m]',fontsize=12)
plt.ylabel('Value [Cnts]', fontsize=12)
plt.plot(x, y,'ko')
plt.plot(x, expf(x,g,k,y0,d))
a_patch=mp.Patch(color='k', label="$TEM_{00}$ Doubleslit ShortMode")
plt.legend(handles=[a_patch],loc="upper left")
plt.show()
Here is my datafile:
Data File of Intensity

Related

Get contour coordinates using alphashape

I have plotted the contour of some data from file, but I need to generate a file with the coordinates of this contour. My code is the following:
import os
import sys
import pandas as pd
import numpy as np
from descartes import PolygonPatch
import matplotlib.pyplot as plt
sys.path.insert(0, os.path.dirname(os.getcwd()))
import alphashape
data1 = pd.read_csv('SDSS_19.txt', sep='\s+', header=None)
data1 = pd.DataFrame(data1)
x = data1[0]
y = data1[1]
points = np.vstack((x, y)).T
fig, ax = plt.subplots(figsize=(20,20))
ax.scatter(x, y, alpha=0.5, color='red')
alpha_shape = alphashape.alphashape(points, 0.6)
ax.add_patch(PolygonPatch(alpha_shape, alpha=0.25))
plt.savefig('contour.png')
plt.show()
The output is the following:
What I need is to calculate the coordinates of some points (the more the best) of the black line (the contour).
any help? Thanks.

Python multivariable nonlinear regression calculation

i was trying to make a curve fit of data and want to find nonlinear regression equation.
thats what my plot looks like i got x,y data which will be my reference data,
then i got x0 and y0 which will be my second point,
dx and dy will be difference between them
when i show this as vector it showed form of
when i convert dx,dy to R and theta it showed x^2+y^2 form,
is it possible to find those equation with it?
here's my current code
import matplotlib.pyplot as plt
import numpy as np
import math
import seaborn as sns
from statsmodels.formula.api import ols
from mpl_toolkits.mplot3d import Axes3D
from scipy.interpolate import griddata
"""setting dpi for graph shown in editor"""
import matplotlib as mpl
mpl.rcParams['figure.dpi'] = 300
import pandas as pd
"""reading data from excel sheet 1"""
df = pd.read_excel(r'C:\Users\JRKIM\Desktop\data\2513data.xlsx')
"""variable selection"""
tx_0 = df.loc[:,'TRUE_x_0']
ty_0 = df.loc[:,'TRUE_y_0']
v_x_0 = df.loc[:,'vx']
v_y_0 = df.loc[:,'vy']
dx0_0 = tx_0-v_x_0
dy0_0 = ty_0-v_y_0
dr0_0 = df.loc[:,'dr']
fig1, ax0 = plt.subplots()
ax0.set_title("delta0 in vector")
qk = ax0.quiver(tx_0,ty_0,dx0_0,dy0_0)
ax0.scatter(tx_0, ty_0, color='r', s=1)
"""3d graph with vector and position """
fig4 = plt.figure()
ax4 = fig4.add_subplot(111, projection='3d')
ax4.scatter(tx_0, ty_0, dr0_0, marker='*',linewidth = 0.01, cmap="jet")
ax4.set_xlabel('X Label')
ax4.set_ylabel('Y Label')
ax4.set_zlabel('dr Label')
you can use scipy.optimize.curve_fit as follows.
from scipy.optimize import curve_fit
def quadratic_function(x, a, b):
return a * x[0]**2 + b * x[1]**2 # + c * x[0]*x[1] if you want to satisfy quadratic form
xdata = np.vstack([np.array(dx0_0).flatten(),np.array(dy0_0).flatten()])
ydata = np.array(dr0_0).flatten()
popt, pcov = curve_fit(quadratic_function,xdata,ydata)
print(popt) # values for a and b
this should get you the coefficients for a and b for the least squares fitting of a*x**2 + b*y**2 = r, you have to further calculate the error and see if the error is low enough for your liking.
Edit: corrected the dimensions of inputs

Plot a poisson distribution graph in python

I would like to plot the Poisson function in Python using Matplotlib. The function is (exp(-5)*5^x)/factorial(x)
import numpy as np
import math
import matplotlib.pyplot as plt
t = np.arange(0, 20, 0.1)
d = []
for i in t:
p = pow(5,i)
q = p/math.factorial(i)
d.append(q)
plt.plot( t, np.exp(-5)*d, 'bs')
plt.show()
But I get this error."Only size^1 arrays can be converted to Python scalars". How can I plot this graph? Thanks in advance
i think your function is not right: it's exp(-5)
import numpy as np
import matplotlib.pyplot as plt
from scipy.special import factorial
t = np.arange(0, 20, 0.1)
d = np.exp(-5)*np.power(5, t)/factorial(t)
plt.plot(t, d, 'bs')
plt.show()
The immediate problem is probably that you are using 't' instead of 'i' in your loop. However, you may want to avoid mixing python lists with numpy arrays. You could do it like,
import numpy as np
import scipy.misc
import math
import matplotlib.pyplot as plt
t = np.arange(0, 20, 0.1)
x = np.power(t, 5)
y = scipy.misc.factorial(t)
plt.plot( t, x / y, 'bs')
plt.show()

Less noisy graph and extra humps in python

Here is the data file:
https://jsfiddle.net/83ygso6u/
Sorry for posting it in jsfiddle... didn't know where else to host it.
Anyway the second column should be ignored.
Here is the code and graph:
import pylab as plb
import math
from pylab import *
import matplotlib.pyplot as plt
data = plb.loadtxt('title_of_datafile.txt')
x = data[:,0]*1000
y= data[:,2]
plt.figure()
plt.title('Some_Title',fontsize=35, y=1.05)
plt.xlabel('Frequency (Hz)',fontsize=30)
plt.ylabel('dBu',fontsize=30)
plt.plot(x,y,'k-', label='Data')
plt.xticks(fontsize = 25, y=-0.008)
plt.yticks(fontsize = 25, x=-0.008)
plt.show()
So you can see this signal is quite noisy, but it does have two distinct peaks at around 4500 Hz and 5500 Hz.
I have been searching around the net and havn't really come across anything that will help me.
How can I extract these peaks and/or clean up the signal in python?
Well I managed to find a solution. Here is the script with the resulting plot.
Script:
import pylab as plb
import math
from pylab import *
import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
from scipy import signal
import peakutils
from peakutils.plot import plot as pplot
data = plb.loadtxt('data_file_name')
x = data[:,0]*1000
y= data[:,2]
y1 = sp.signal.medfilt(y,431) # remove noise to the signal
indexes = peakutils.indexes(y1, thres=0.00005, min_dist=1400) #determine peaks
x_new = x[indexes]
plt.figure()
plt.subplot(1,2,1)
plt.title('some_title_1',fontsize=35, y=1.05)
plt.xlabel('Frequency (Hz)',fontsize=30)
plt.ylabel('Signal (dBu)',fontsize=30)
plt.plot(x,y,'r-', label='Raw Data')
plt.plot(x,y1,'b-', label='Cleaned up Signal')
plt.plot(x_new[3:6],y1[indexes][3:6],'k^',markersize=10, label='Peaks')
plt.xticks(fontsize = 25, y=-0.008)
plt.yticks(fontsize = 25, x=-0.008)
plt.legend(loc=1,prop={'size':30})
plt.subplot(1,2,2)
for i,j in zip(x_new[3:6], y1[indexes][3:6]):
plt.annotate(str(i)+ " Hz",xy=(i,j+0.5),fontsize=15)
plt.title('some_title_2',fontsize=35, y=1.05)
plt.xlabel('Frequency (Hz)',fontsize=30)
plt.ylabel('Signal (dBu)',fontsize=30)
plt.plot(x,y,'r-', label='Data')
plt.plot(x,y1,'b-')
plt.plot(x_new[3:6],y1[indexes][3:6],'k^',markersize=10)
plt.xticks(fontsize = 25, y=-0.008)
plt.yticks(fontsize = 25, x=-0.008)
plt.xlim([3000, 6000])
plt.ylim([-90, -75])
plt.subplots_adjust(hspace = 0.6)
plt.show()

Python 2.7: Trouble fitting a Poisson distributed histogram; curve drops off quickly

I have a discrete set of data which looks Poisson distributed between 0 and 90. I'm trying to curve fit the data. My code is the following:
import matplotlib.pyplot as plt
import matplotlib
matplotlib.style.use('ggplot')
import numpy as np
from scipy.stats import poisson
from scipy.optimize import curve_fit
from scipy.misc import factorial
plt.figure(figsize = (10, 10))
entries, bin_edges, patches = plt.hist(data, bins = 90, range = [1, 90], normed = True)
bin_middles = 0.5*(bin_edges[1:] + bin_edges[:-1])
def poisson(k, lamb):
return (lamb**k/factorial(k)) * np.exp(-lamb)
params, cov = curve_fit(poisson, bin_middles, entries)
x_plot = np.linspace(1, 90, 90)
plt.plot(x_plot, poisson(x_plot, *params), 'b--', lw = 2)
plt.axvline(np.mean(data), linestyle = '--', color = 'g')
plt.ylim(0, max(entries)+max(entries)/4)
plt.xlim([0, max(x_plot)])
I can't identify why the curve is sitting to the left and the values are extremely small. Thanks for any help!
This is not really an answer, but I can't get the picture into the comments. I'm getting a nice fit on some synthetic data with your code (added proper imports):
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from scipy.misc import factorial
%matplotlib inline
plt.figure(figsize = (10, 10))
#make up some synthetic data
data = np.random.poisson(3, 5000000)
entries, bin_edges, patches = plt.hist(data, bins = 90, range = [1, 90], normed = True)
bin_middles = 0.5*(bin_edges[1:] + bin_edges[:-1])
def poisson(k, lamb):
return (lamb**k/ factorial(k)) * np.exp(-lamb)
params, cov = curve_fit(poisson, bin_middles, entries)
x_plot = np.linspace(1, 30, 30)
plt.plot(x_plot, poisson(x_plot, *params), 'r', lw = 2)
Your data are definitely not very Poissonian (relationship between peak and width is wrong, plus the very slow dropoff to the right), but I can't find the reason why your plot is so far off, either.

Categories