Python

How to do exponential and logarithmic curve fitting in Python I found only polynomial fitting

20 September 2026 · 11 min read

How to do exponential and logarithmic curve fitting in Python I found only polynomial fitting

Curve fitting is a crucial technique in data analysis and modeling, enabling us to understand the relationships between variables and make predictions. While polynomial fitting is widely known, many phenomena are better described by exponential or logarithmic functions. This article will guide you through the process of performing exponential and logarithmic curve fitting in Python, addressing the common challenge that many resources focus solely on polynomial approaches. We’ll explore how to leverage Python’s powerful libraries, such as NumPy and SciPy, to fit these non-linear curves to your data. Mastering these techniques opens doors to a deeper understanding of scientific data, financial modeling, and numerous other applications. Understanding these techniques allows you to interpret trends and patterns that polynomial fitting simply cannot capture, providing a more accurate representation of the underlying data-generating process. Let’s dive in and unlock the power of exponential and logarithmic curve fitting.

Understanding Exponential and Logarithmic Functions

Before diving into the Python implementation, it’s essential to understand the mathematical forms of exponential and logarithmic functions. An exponential function takes the form y = a exp(bx) + c, where ‘a’ represents the scaling factor, ‘b’ determines the rate of growth or decay, ‘x’ is the independent variable, and ‘c’ is the vertical shift. Conversely, a logarithmic function can be expressed as y = a log(bx) + c, where ‘a’ scales the logarithm, ‘b’ affects the horizontal compression/expansion, ‘x’ is the independent variable, and ‘c’ is the vertical shift. Choosing the appropriate function depends on the nature of the relationship you’re trying to model.

Exponential functions are often used to model growth or decay processes, such as population growth, radioactive decay, or the spread of a virus. Logarithmic functions, on the other hand, are useful for modeling phenomena where the rate of change decreases as the independent variable increases, such as the relationship between sound intensity and perceived loudness or the growth of a tree over time. Recognizing which function type best suits your data is the first crucial step in effective curve fitting. Consider the underlying process generating your data to make the most informed choice. For example, data showing an accelerating growth is a strong indicator of exponential behavior.

Consider a real-world example: the charging of a capacitor. The voltage across the capacitor increases exponentially over time. Fitting an exponential curve to voltage measurements taken during the charging process allows you to determine the time constant of the circuit, a crucial parameter for circuit design and analysis. According to a study by the IEEE, accurate curve fitting is essential for the accurate prediction and modeling of electrical circuits. IEEE Website offers valuable resources.

Setting Up Your Python Environment

To perform exponential and logarithmic curve fitting in Python, you’ll need to install a few essential libraries. NumPy is fundamental for numerical computations, providing support for arrays and mathematical functions. SciPy offers advanced scientific computing tools, including the curve_fit function, which we’ll use for the actual fitting process. Matplotlib is used for visualizing the data and the fitted curves. Ensure you have these libraries installed using pip: pip install numpy scipy matplotlib. This sets the stage for analyzing your dataset effectively.

Once the libraries are installed, import them into your Python script: import numpy as np, import scipy.optimize as opt, and import matplotlib.pyplot as plt. Defining your data is the next step. This usually involves creating NumPy arrays for your independent variable (x) and dependent variable (y). Data preparation is crucial for accurate curve fitting. Ensure your data is clean, free of outliers (or that outliers are handled appropriately), and that the data is properly scaled. A pre-processing step can save significant time and improve the accuracy of your results.

For example, let’s say you have collected data on bacterial growth in a petri dish over time. You would create two NumPy arrays: one for time (in hours) and one for the number of bacteria. With your environment set up and your data prepared, you’re ready to implement the curve fitting algorithms. The following list highlights why these libraries are important:

  • NumPy: Provides efficient array operations and mathematical functions.
  • SciPy: Offers the curve_fit function for non-linear least squares optimization.
  • Matplotlib: Enables visualization of data and fitted curves.

Implementing Exponential Curve Fitting

Now, let’s focus on fitting an exponential curve to your data. The key is to define a function that represents the exponential model. This function will take the independent variable (x) and the parameters you want to estimate (a, b, and c) as inputs. The curve_fit function from SciPy will then find the optimal values for these parameters that minimize the difference between the model’s predictions and your actual data. This minimization is performed using a least-squares approach, which aims to find the parameter values that best fit the observed data.

Here’s a Python code snippet demonstrating the process:

import numpy as np import scipy.optimize as opt import matplotlib.pyplot as plt Define the exponential function def exponential_func(x, a, b, c): return a  np.exp(b  x) + c Sample data x_data = np.array([0, 1, 2, 3, 4, 5]) y_data = np.array([2, 5, 11, 23, 47, 95]) Perform curve fitting popt, pcov = opt.curve_fit(exponential_func, x_data, y_data, p0=[1, 1, 1]) Extract the optimized parameters a, b, c = popt Generate points for the fitted curve x_fit = np.linspace(min(x_data), max(x_data), 100) y_fit = exponential_func(x_fit, a, b, c) Plot the data and the fitted curve plt.plot(x_data, y_data, 'o', label='Data') plt.plot(x_fit, y_fit, '-', label='Fitted Curve') plt.xlabel('X') plt.ylabel('Y') plt.title('Exponential Curve Fitting') plt.legend() plt.show() 

In this example, p0=[1, 1, 1] provides initial guesses for the parameters a, b, and c. Providing good initial guesses can significantly improve the convergence and accuracy of the fitting process. Remember that the curve_fit function returns both the optimized parameters (popt) and the covariance matrix (pcov), which provides information about the uncertainty in the parameter estimates. It’s also good practice to check the pcov matrix to understand the error associated with each parameter. This information is crucial for assessing the reliability of your fitted model. The curve_fit function is further detailed on the SciPy Documentation.

Implementing Logarithmic Curve Fitting

Fitting a logarithmic curve follows a similar process to fitting an exponential curve. The primary difference lies in defining the logarithmic function. Again, you’ll use the curve_fit function from SciPy, but this time, you’ll provide it with a logarithmic model. This model will take the independent variable (x) and the parameters (a, b, and c) as inputs, just like the exponential model. The curve_fit function will then find the optimal parameter values that minimize the difference between the model’s predictions and your observed data.

Here’s the code for logarithmic curve fitting:

import numpy as np import scipy.optimize as opt import matplotlib.pyplot as plt Define the logarithmic function def logarithmic_func(x, a, b, c): return a  np.log(b  x) + c Sample data x_data = np.array([1, 2, 3, 4, 5, 6]) y_data = np.array([2, 3, 3.7, 4.2, 4.5, 4.8]) Perform curve fitting popt, pcov = opt.curve_fit(logarithmic_func, x_data, y_data, p0=[1, 1, 1]) Extract the optimized parameters a, b, c = popt Generate points for the fitted curve x_fit = np.linspace(min(x_data), max(x_data), 100) y_fit = logarithmic_func(x_fit, a, b, c) Plot the data and the fitted curve plt.plot(x_data, y_data, 'o', label='Data') plt.plot(x_fit, y_fit, '-', label='Fitted Curve') plt.xlabel('X') plt.ylabel('Y') plt.title('Logarithmic Curve Fitting') plt.legend() plt.show() 

Similar to exponential fitting, providing good initial guesses for the parameters (a, b, and c) is crucial for successful logarithmic curve fitting. The p0=[1, 1, 1] argument in the curve_fit function allows you to specify these initial guesses. Careful selection of initial guesses can significantly improve the speed and accuracy of the fitting process. Moreover, always examine the covariance matrix (pcov) returned by curve_fit to assess the uncertainty in your parameter estimates. Understanding this uncertainty is vital for evaluating the reliability of your model. It’s also worth noting that logarithmic functions are only defined for positive values of x. Ensure your x-data meets this requirement before attempting to fit a logarithmic curve.

Infographic here
Evaluating the Goodness of Fit ------------------------------

After fitting your curve, it’s crucial to evaluate how well the model fits the data. Several metrics can help you assess the goodness of fit. R-squared (coefficient of determination) is a common metric that represents the proportion of variance in the dependent variable that can be predicted from the independent variable(s). A higher R-squared value indicates a better fit. However, R-squared alone can be misleading, especially with non-linear models.

Other metrics include Mean Squared Error (MSE) and Root Mean Squared Error (RMSE), which measure the average squared difference and the square root of the average squared difference between the predicted and actual values, respectively. Lower values of MSE and RMSE indicate a better fit. Visual inspection of the fitted curve along with the data points is also essential. Look for systematic deviations or patterns in the residuals (the differences between the observed and predicted values). These patterns can indicate that the model is not capturing the underlying relationship adequately and that a different model may be more appropriate. To implement R-squared calculation, you can use code similar to this:

from sklearn.metrics import r2_score Calculate R-squared r_squared = r2_score(y_data, exponential_func(x_data, popt)) print(f"R-squared: {r_squared}") 

Remember to always critically evaluate your model’s performance using a combination of statistical metrics and visual inspection. No single metric tells the whole story, and a thorough evaluation is essential for ensuring the reliability of your model. Here’s a list of key metrics and considerations:

  • R-squared (Coefficient of Determination): Measures the proportion of variance explained by the model.
  • Mean Squared Error (MSE) and Root Mean Squared Error (RMSE): Measure the average prediction error.
  • Visual Inspection: Examine the plot of the fitted curve and the residuals for systematic patterns.

FAQ

Q: What if the curve\_fit function doesn't converge?
A: Non-convergence can occur due to poor initial parameter guesses or issues with the data itself. Try providing different initial guesses (the p0 argument), scaling your data, or checking for outliers.
Q: How do I choose between an exponential and a logarithmic model?
A: Consider the nature of the relationship you're trying to model. Exponential functions are suitable for growth or decay processes, while logarithmic functions are useful when the rate of change decreases as the independent variable increases.
Q: Can I fit more complex exponential or logarithmic models?
A: Yes, you can define more complex models by adding more parameters or combining exponential and logarithmic terms. However, be cautious of overfitting, which can lead to poor generalization.
Q: What are the limitations of curve fitting?
A: Curve fitting provides a mathematical approximation of the data. It's essential to validate the fitted curve with additional data or theoretical considerations to ensure it accurately represents the underlying phenomenon.
**Exponential and logarithmic curve fitting in Python** empowers you to model a wider range of phenomena compared to just polynomial fitting. By leveraging libraries like NumPy and SciPy, you can effectively fit these curves to your data, gaining valuable insights and making accurate predictions. Remember to carefully choose the appropriate function, prepare your data, provide good initial parameter guesses, and thoroughly evaluate the **Question & Answer :**

I have a set of data and I want to compare which line describes it best (polynomials of different orders, exponential or logarithmic).

I use Python and Numpy and for polynomial fitting there is a function polyfit(). But I found no such functions for exponential and logarithmic fitting.

Are there any? Or how to solve it otherwise?

For fitting y = A + B log x, just fit y against (log x).

>>> x = numpy.array([1, 7, 20, 50, 79]) >>> y = numpy.array([10, 19, 30, 35, 51]) >>> numpy.polyfit(numpy.log(x), y, 1) array([ 8.46295607, 6.61867463]) # y ≈ 8.46 log(x) + 6.62 

For fitting y = AeBx, take the logarithm of both side gives log y = log A + Bx. So fit (log y) against x.

Note that fitting (log y) as if it is linear will emphasize small values of y, causing large deviation for large y. This is because polyfit (linear regression) works by minimizing ∑iY)2 = ∑i (YiŶi)2. When Yi = log yi, the residues ΔYi = Δ(log yi) ≈ Δyi / |yi|. So even if polyfit makes a very bad decision for large y, the “divide-by-|y|” factor will compensate for it, causing polyfit favors small values.

This could be alleviated by giving each entry a “weight” proportional to y. polyfit supports weighted-least-squares via the w keyword argument.

>>> x = numpy.array([10, 19, 30, 35, 51]) >>> y = numpy.array([1, 7, 20, 50, 79]) >>> numpy.polyfit(x, numpy.log(y), 1) array([ 0.10502711, -0.40116352]) # y ≈ exp(-0.401) * exp(0.105 * x) = 0.670 * exp(0.105 * x) # (^ biased towards small values) >>> numpy.polyfit(x, numpy.log(y), 1, w=numpy.sqrt(y)) array([ 0.06009446, 1.41648096]) # y ≈ exp(1.42) * exp(0.0601 * x) = 4.12 * exp(0.0601 * x) # (^ not so biased) 

Note that Excel, LibreOffice and most scientific calculators typically use the unweighted (biased) formula for the exponential regression / trend lines. If you want your results to be compatible with these platforms, do not include the weights even if it provides better results.


Now, if you can use scipy, you could use scipy.optimize.curve_fit to fit any model without transformations.

For y = A + B log x the result is the same as the transformation method:

>>> x = numpy.array([1, 7, 20, 50, 79]) >>> y = numpy.array([10, 19, 30, 35, 51]) >>> scipy.optimize.curve_fit(lambda t,a,b: a+b*numpy.log(t), x, y) (array([ 6.61867467, 8.46295606]), array([[ 28.15948002, -7.89609542], [ -7.89609542, 2.9857172 ]])) # y ≈ 6.62 + 8.46 log(x) 

For y = AeBx, however, we can get a better fit since it computes Δ(log y) directly. But we need to provide an initialize guess so curve_fit can reach the desired local minimum.

>>> x = numpy.array([10, 19, 30, 35, 51]) >>> y = numpy.array([1, 7, 20, 50, 79]) >>> scipy.optimize.curve_fit(lambda t,a,b: a*numpy.exp(b*t), x, y) (array([ 5.60728326e-21, 9.99993501e-01]), array([[ 4.14809412e-27, -1.45078961e-08], [ -1.45078961e-08, 5.07411462e+10]])) # oops, definitely wrong. >>> scipy.optimize.curve_fit(lambda t,a,b: a*numpy.exp(b*t), x, y, p0=(4, 0.1)) (array([ 4.88003249, 0.05531256]), array([[ 1.01261314e+01, -4.31940132e-02], [ -4.31940132e-02, 1.91188656e-04]])) # y ≈ 4.88 exp(0.0553 x). much better. 

comparison of exponential regression