Reputation: 444
import matplotlib.pylab as plt
import numpy as np
#initial data
data=np.loadtxt('profile_nonoisebigd02.txt')
x=data[:,0]
y=data[:,1]
#first derivatives
dx= np.gradient(data[:,0])
dy = np.gradient(data[:,1])
#second derivatives
d2x = np.gradient(dx)
d2y = np.gradient(dy)
#calculation of curvature from the typical formula
curvature = np.abs(dx * d2y - d2x * dy) / (dx * dx + dy * dy)**1.5
Can anyone help me out as to where am I going wrong with the curvature ? The set of points give me a parabola, but curvature is not what I expect.
Upvotes: 1
Views: 7278
Reputation: 11602
It seems that your data just isn't smooth enough; I used pandas to replace x, y, dx, dy, d2x, d2y and curvature by rolling means for different values window sizes. As the window size increases, the curvature starts to look more and more like what you'd expect to see for a smooth parabola (legend gives window size):
For the reference, here is the plot of your original data:
The code used to create the smoothed frames:
def get_smooth(smoothing=10, return_df=False):
data=np.loadtxt('profile_nonoisebigd02.txt')
if return_df:
return pd.DataFrame(data)
df = pd.DataFrame(data).sort_values(by=0).reset_index(drop=True).rolling(smoothing).mean().dropna()
# first derivatives
df['dx'] = np.gradient(df[0])
df['dy'] = np.gradient(df[1])
df['dx'] = df.dx.rolling(smoothing, center=True).mean()
df['dy'] = df.dy.rolling(smoothing, center=True).mean()
# second derivatives
df['d2x'] = np.gradient(df.dx)
df['d2y'] = np.gradient(df.dy)
df['d2x'] = df.d2x.rolling(smoothing, center=True).mean()
df['d2y'] = df.d2y.rolling(smoothing, center=True).mean()
# calculation of curvature from the typical formula
df['curvature'] = df.eval('abs(dx * d2y - d2x * dy) / (dx * dx + dy * dy) ** 1.5')
# mask = curvature < 100
df['curvature'] = df.curvature.rolling(smoothing, center=True).mean()
df.dropna(inplace=True)
return df[0], df.curvature
Upvotes: 5