0

I have a set of 50 data points that look like this: data points

and want to fit a curve like this: data points with curve If I fit log(x) I get a nice linear relation (kind of) like this: linear curve But I really want it to be the second curve which means that I somehow have to change it back, but saving the fitted curve.

Probably very easy but I am lost.

Edit: This is the polyfit x,y, deg=3 curve that seems overfitted. enter image description here

Mactilda
  • 393
  • 6
  • 18
  • Is there a parameter to keep the x-axis as x-values instead of log(x) values? Does polyfit(x,y, deg=3) work instead of polyfit(log(x),y,deg=3)? – Richard K Yu Sep 09 '19 at 11:14
  • Try this question: https://stackoverflow.com/questions/3433486/how-to-do-exponential-and-logarithmic-curve-fitting-in-python-i-found-only-poly/15369787#15369787 – Itamar Mushkin Sep 09 '19 at 11:20
  • Possible duplicate of [How to do exponential and logarithmic curve fitting in Python? I found only polynomial fitting](https://stackoverflow.com/questions/3433486/how-to-do-exponential-and-logarithmic-curve-fitting-in-python-i-found-only-poly) – Itamar Mushkin Sep 09 '19 at 11:20
  • why `deg=3` if you expect a linear relation? – filippo Sep 09 '19 at 11:27
  • @RichardKYu Kind of. it produces a curve that isn't far off the desired one, but not quite. – Mactilda Sep 09 '19 at 12:07
  • @Mactilda do you want a polynomial curve or a logarithmic curve? You might need to use a different function instead of polyfit if you want a logarithmic curve. – Richard K Yu Sep 09 '19 at 12:17
  • 1
    check out the logfit function coded by tel (third answer) in this link, I think it is what you are looking for: https://stackoverflow.com/questions/49944018/fit-a-logarithmic-curve-to-data-points-and-extrapolate-out-in-numpy – Richard K Yu Sep 09 '19 at 12:21
  • @RichardKYu I am -obviously- new to this and I think you are right about using a different function. I have looked at the other questions as suggested but I am afraid I lack the knowledge needed to understand how they help me. Sorry. – Mactilda Sep 09 '19 at 12:23
  • @RichardKYu Thanks that was helpful - I haven't solved it, but at least it was comprehensible and I've got a place to start. – Mactilda Sep 09 '19 at 12:34

1 Answers1

1

This is more a problem about linearization of a logarithmic function then about fitting itself. If your data follow a simple logarithmic relation like:

log

then you can make a linear regression of y versus log(x), where the slopes will be equal to A and your intercept to A log(k). You can then use these parameters to determine A (simply the slope) and k (e**(intercept/slope)) and get your results.

I would implement this as follows:

import scipy.stats as stats
import numpy as np
import matplotlib.pyplot as plt

slope, intercept, r_value, p_value, std_err = stats.linregress(np.log(x), y)

plt.figure()
plt.plot(x,y,'o')
plt.plot(x,slope*np.log(x*np.e**(intercept/slope)))
baccandr
  • 1,090
  • 8
  • 15
  • Yes! Thank you! If I want to calculate the RSS and the R2 coefficient for this curve - how would I go about? – Mactilda Sep 25 '19 at 10:44
  • and what does the 'o' stand for? Sorry it might be really basic but I am a newbie ;) – Mactilda Sep 25 '19 at 11:00
  • Have a look at the documentation of scipy [stats.linregress function](https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.linregress.html): r_value is the correlation coefficient so you just have to take its square for R2. Concerning RSS you can calculate it directly from its [definition](https://en.wikipedia.org/wiki/Residual_sum_of_squares) – baccandr Sep 25 '19 at 12:17
  • and 'o' it is just to plot your data as dots, otherwise plt.plot would give you a line by default. For more marker options check the [documentation](https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.plot.html) – baccandr Sep 25 '19 at 12:20