It looks like the method used to do the fits is stochastic. From the pwlf source code, fit calls the function scipy.optimize.differential_evolution. The Scipy docs for this function describe it as a stochastic method to determine a global minimum of a function.

It appears that with the default settings used by pwlf, its not quite converged or at least its approaching convergence from different directions each time. You maybe able to edit the keywords so that the optimization will do a more stringent search for the true minimum. For example, atol sets the absolute tolerance for convergence. You also set seed to a consistent value to at least get the same result every time, even if it may not have found the "true" minimum. Just be aware that if you change one of the keywords, you need to explicitly write out all the others, as the **kwargs passed into fit appear to overwrite the defaults that would be passed to differential_evolution.

Answer from Tyberius on Stack Overflow
🌐
PyPI
pypi.org › project › pwlf
pwlf · PyPI
@Manual{pwlf, author = {Jekel, Charles F. and Venter, Gerhard}, title = {{pwlf:} A Python Library for Fitting 1D Continuous Piecewise Linear Functions}, year = {2019}, url = {https://github.com/cjekel/piecewise_linear_fit_py} }
      » pip install pwlf
    
Published   Jul 26, 2025
Version   2.5.2
🌐
ResearchGate
researchgate.net › publication › 331231072_pwlf_A_Python_Library_for_Fitting_1D_Continuous_Piecewise_Linear_Functions
(PDF) pwlf: A Python Library for Fitting 1D Continuous Piecewise Linear Functions
February 20, 2019 - ... We then applied the PieceWise Linear Functions (PWLF) Python package to further decompose the trend in elevation change into multiple piecewise linear function models
🌐
Jekel
jekel.me › piecewise_linear_fit_py
pwlf: piecewise linear fitting — pwlf 2.5.2 documentation
obtain the equations of fitted pwlf · weighted least squares fit · reproducible results · pwlf package contents · pwlf.PiecewiseLinFit · PiecewiseLinFit · About · Requirements · License · Index · Search Page · Installation · How it works · Examples · pwlf package contents ·
🌐
Anaconda.org
anaconda.org › conda-forge › pwlf
Pwlf - conda-forge
conda-forge/pwlf · Community · fit piecewise linear data for a specified number of line segments · Copied fromcf-staging / pwlf · Overview · Files 261 · Labels 1 · Badges · Versions · 2.5.1 · To install this package, run one of the following: $conda install conda-forge::pwlf ·
🌐
FreshPorts
freshports.org › math › py-pwlf
FreshPorts -- math/py-pwlf: Fit piecewise linear functions to data
pwlf is a Python library for fitting continuous piecewise linear functions to data. Just specify the number of line segments you desire and provide the data.
🌐
GitHub
github.com › cjekel › piecewise_linear_fit_py › blob › master › pwlf › pwlf.py
piecewise_linear_fit_py/pwlf/pwlf.py at master · cjekel/piecewise_linear_fit_py
fit piecewise linear data for a specified number of line segments - piecewise_linear_fit_py/pwlf/pwlf.py at master · cjekel/piecewise_linear_fit_py
Author   cjekel
🌐
Jekel
jekel.me › piecewise_linear_fit_py › pwlf.html
pwlf package contents — pwlf 2.5.2 documentation
>>> import pwlf >>> my_pwlf = pwlf.PiecewiseLinFit(x, y) >>> breaks = [0.0, 0.5, 1.0] >>> A = assemble_regression_matrix(breaks, self.x_data)
🌐
ResearchGate
researchgate.net › profile › Charles-Jekel-2 › publication › 331231072_pwlf_A_Python_Library_for_Fitting_1D_Continuous_Piecewise_Linear_Functions › links › 5c6d607aa6fdcc404ec03c53 › pwlf-A-Python-Library-for-Fitting-1D-Continuous-Piecewise-Linear-Functions.pdf pdf
pwlf: A Python Library for Fitting 1D Continuous Piecewise Linear Functions
April 1, 2017 - This paper introduces a Python library for fitting continuous piecewise linear · functions to 1D data. The library is called pwlf and was first available online · on April 1, 2017. The library includes a number of functions related to fitting · continuous piecewise linear models.
Find elsewhere
🌐
Jekel
jekel.me › piecewise_linear_fit_py › stubs › pwlf.PiecewiseLinFit.html
pwlf.PiecewiseLinFit — pwlf 2.5.2 documentation
class pwlf.PiecewiseLinFit(x, y, disp_res=False, lapack_driver='gelsd', degree=1, weights=None, seed=None)¶
🌐
GitHub
github.com › PanPalitta › piecewise_analysis
GitHub - PanPalitta/piecewise_analysis: Python script for fitting and comparing piecewise linear models
The script uses piecewise regression library "pwlf.py" by Charles Jekel for 3-segment regression.
Author   PanPalitta
🌐
GitHub
github.com › cjekel › piecewise_linear_fit_py
GitHub - cjekel/piecewise_linear_fit_py: fit piecewise linear data for a specified number of line segments · GitHub
@Manual{pwlf, author = {Jekel, Charles F. and Venter, Gerhard}, title = {{pwlf:} A Python Library for Fitting 1D Continuous Piecewise Linear Functions}, year = {2019}, url = {https://github.com/cjekel/piecewise_linear_fit_py} }
Starred by 348 users
Forked by 65 users
Languages   Python
🌐
Snyk
snyk.io › advisor › python packages › pwlf
pwlf - Python Package Health Analysis | Snyk
fit piecewise linear functions to data. Visit Snyk Advisor to see a full health score report for pwlf, including popularity, security, maintenance & community analysis. The python package pwlf receives a total of 28,236 weekly downloads. As such, pwlf popularity was classified as a recognized.
Top answer
1 of 12
88

You can use numpy.piecewise() to create the piecewise function and then use curve_fit(), Here is the code

from scipy import optimize
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline

x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ,11, 12, 13, 14, 15], dtype=float)
y = np.array([5, 7, 9, 11, 13, 15, 28.92, 42.81, 56.7, 70.59, 84.47, 98.36, 112.25, 126.14, 140.03])

def piecewise_linear(x, x0, y0, k1, k2):
    return np.piecewise(x, [x < x0], [lambda x:k1*x + y0-k1*x0, lambda x:k2*x + y0-k2*x0])

p , e = optimize.curve_fit(piecewise_linear, x, y)
xd = np.linspace(0, 15, 100)
plt.plot(x, y, "o")
plt.plot(xd, piecewise_linear(xd, *p))

the output:

For an N parts fitting, please reference segments_fit.ipynb

2 of 12
39

You can use pwlf to perform continuous piecewise linear regression in Python. This library can be installed using pip.

There are two approaches in pwlf to perform your fit:

  1. You can fit for a specified number of line segments.
  2. You can specify the x locations where the continuous piecewise lines should terminate.

Let's go with approach 1 since it's easier, and will recognize the 'gradient change point' that you are interested in.

I notice two distinct regions when looking at the data. Thus it makes sense to find the best possible continuous piecewise line using two line segments. This is approach 1.

import numpy as np
import matplotlib.pyplot as plt
import pwlf

x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
y = np.array([5, 7, 9, 11, 13, 15, 28.92, 42.81, 56.7, 70.59,
              84.47, 98.36, 112.25, 126.14, 140.03])

my_pwlf = pwlf.PiecewiseLinFit(x, y)
breaks = my_pwlf.fit(2)
print(breaks)

[ 1. 5.99819559 15. ]

The first line segment runs from [1., 5.99819559], while the second line segment runs from [5.99819559, 15.]. Thus the gradient change point you asked for would be 5.99819559.

We can plot these results using the predict function.

x_hat = np.linspace(x.min(), x.max(), 100)
y_hat = my_pwlf.predict(x_hat)

plt.figure()
plt.plot(x, y, 'o')
plt.plot(x_hat, y_hat, '-')
plt.show()

🌐
Pydigger
pydigger.com › pypi › pwlf
pwlf
June 26, 2020 - See `this\nexample <https://github.com/cjekel/piecewise_linear_fit_py/blob/master/examples/sineWave_time_compare.py>`__\nwhich runs fit() function, then runs the fitfast() to compare the\nruntime differences!\n\nInstallation\n============\n\nPython Package Index (PyPI)\n---------------------------\n\nYou can now install with pip.\n\n::\n\n python -m pip install pwlf\n\nConda\n-----\n\nIf you have conda, you can also install from conda-forge.\n\n::\n\n conda install -c conda-forge pwlf\n\nFrom source\n-----------\n\nOr clone the repo\n\n::\n\n git clone https://github.com/cjekel/piecewise_linea
🌐
Jekel
jekel.me › piecewise_linear_fit_py › examples.html
Examples — pwlf 2.5.2 documentation
from GPyOpt.methods import BayesianOptimization # initialize piecewise linear fit with your x and y data my_pwlf = pwlf.PiecewiseLinFit(x, y) # define your objective function def my_obj(x): # define some penalty parameter l # you'll have to arbitrarily pick this # it depends upon the noise ...
🌐
GitHub
github.com › cjekel › piecewise_linear_fit_py › blob › master › examples › fitForSpecifiedNumberOfLineSegments.py
piecewise_linear_fit_py/examples/fitForSpecifiedNumberOfLineSegments.py at master · cjekel/piecewise_linear_fit_py
my_pwlf = pwlf.PiecewiseLinFit(x, y) · # fit the data for four line segments · res = my_pwlf.fit(4) · # predict for the determined points · xHat = np.linspace(min(x), max(x), num=10000) yHat = my_pwlf.predict(xHat) · # Get the slopes · my_slopes = my_pwlf.slopes ·
Author   cjekel
🌐
ResearchGate
researchgate.net › figure › Example-of-fitting-a-continuous-piecewise-linear-function-with-breakpoints-occurring-at_fig1_331231072
Example of fitting a continuous piecewise linear function with... | Download Scientific Diagram
Download scientific diagram | Example of fitting a continuous piecewise linear function with breakpoints occurring at [0.0, 7.0, 16.0]. from publication: pwlf: A Python Library for Fitting 1D Continuous Piecewise Linear Functions | A Python ...
🌐
Programmersought
programmersought.com › article › 88965893107
pwlf: A Python Library for Fitting 1D Continuous Piecewise Linear Functions. - Programmer Sought
# initialize piecewise linear fit with your x and y data import pwlf my_pwlf = pwlf.PiecewiseLinFit(x, y) # fit the data for four line segments res = my_pwlf.fit(4) # predict for the determined points xHat = np.linspace(min(x), max(x), num=10000) yHat = my_pwlf.predict(xHat) # plot the results plt.figure() plt.plot(x, y, 'o') plt.plot(xHat, yHat, '-') plt.show()