Msquare
Msquare

Reputation: 835

Python how to control curvature when joining two points

I have a original curve. I am developing a model curve matching closely the original curve. Everything is working fine but not matching. How to control the curvature of my model curve? Below code is based on answer here.

My code:

def curve_line(point1, point2):
    a = (point2[1] - point1[1])/(np.cosh(point2[0]) - np.cosh(point1[0]))
    b = point1[1] - a*np.sinh(point1[0])
    x = np.linspace(point1[0], point2[0],100).tolist()
    y = (a*np.cosh(x) + b).tolist()
    return x,y
###### A sample of my code is given below
point1 = [10,100]
point2 = [20,50]
x,y = curve_line(point1, point2)

plt.plot(point1[0], point1[1], 'o')
plt.plot(point2[0], point2[1], 'o')
plt.plot(x,y)  ## len(x)

My present output:

enter image description here

I tried following function as well:

y = (50*np.exp(-x/10) +2.5)

The output is:

enter image description here

Upvotes: 2

Views: 1171

Answers (1)

Stef
Stef

Reputation: 30579

Instead of just guessing the right parameters of your model function, you can fit a model curve to your data using curve_fit.

import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt

x = np.array([ 1.92, 14.35, 21.50, 25.27, 27.34, 30.32, 32.31, 34.09, 34.21])
y = np.array([8.30, 8.26, 8.13, 7.49, 6.66, 4.59, 2.66, 0.60, 0.06])

def fun(x, a, b, c):
    return a * np.cosh(b * x) + c
coef,_ = curve_fit(fun, x, y)

plt.plot(x, y, label='Original curve')
plt.plot(x, fun(x, *coef), label=f'Model: %5.3f cosh(%4.2f x + %4.2f)' % tuple(coef) )
plt.legend()
plt.show()

enter image description here

If it is important that the start and end points are closely fitted, you can pass uncertainties to curve_fit, adjusting them to lower values towards the ends, e.g. by

s = np.ones(len(x))
s[1:-1] = s[1:-1] * 3
coef,_ = curve_fit(fun, x, y, sigma=s)

enter image description here

Your other approach a * np.exp(b * x) + c will also work and gives -0.006 exp(0.21 x + 8.49).

In some cases you'll have to provide an educated guess for the initial values of the coefficients to curve_fit (it uses 1 as default).

Upvotes: 2

Related Questions