I'm trying to plot some visualisations with matplotlib, and in one of my functions, I check if waves are logarithmic. This is my current working version:
import numpy as np
def is_logarithmic(waves):
def expfunc(x, a, b, c):
return a*np.exp(b*x) + c
wcopy = list(waves)
wcopy.sort()
# If the ratio of x-max : x-min < 10, don't use a logarithmic scale
# (at least in matplotlib)
if (wcopy[-1] / wcopy[0]) < 10:
return False
# Take a guess at whether it is logarithmic by seeing how well the x-scale
# fits an exponential curve
diffs = []
for ii in range(len(wcopy) - 1):
diffs.append(wcopy[ii + 1] - wcopy[ii])
# Fit the diffs to an exponential curve
x = np.arange(len(wcopy)-1)
try:
popt, pcov = curve_fit(expfunc, x, diffs)
except Exception as e:
print e
popt = [0.0, 0.0, 0.0]
pcov = np.inf
# If a > 0.5 and covsum < 1000.0
# use a logarithmic scale.
if type(pcov) == float:
# It's probably np.inf
covsum = pcov
else:
covsum = pcov.diagonal().sum()
res = (covsum < 1000.0) & (popt[0] > 0.5)
return res
I'm trying to find an alternative to scipy's curve_fit()
, because I don't want to install such a big library just to use that one function. Is there something else I can use, or a combination of other functions from using ideally just numpy and matplotlib, to get a similar result?
Numpy can do linear (numpy.linalg.lstsq
) and polynomial fits (numpy.polyfit
). In general you need scipy for fitting to functions you define yourself (scipy uses the fortran minpack while numpy is built only with C).
However, for your example, you could use a similar approach to this question to fit an exp. Basically, take the logatithm of both sides of the equation and use numpy.polyfit
.
You can also use the lmfit.models
library which has a lot of predefined models.
https://lmfit.github.io/lmfit-py/
https://lmfit.github.io/lmfit-py/builtin_models.html#exponential-and-power-law-models
It also supports custom functions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With