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

Answer from HYRY on Stack Overflow
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()

🌐
NumPy
numpy.org › devdocs › reference › generated › numpy.piecewise.html
numpy.piecewise — NumPy v2.5.dev0 Manual
Define the signum function, which is -1 for x < 0 and +1 for x >= 0. >>> x = np.linspace(-2.5, 2.5, 6) >>> np.piecewise(x, [x < 0, x >= 0], [-1, 1]) array([-1., -1., -1., 1., 1., 1.])
Discussions

How to do piecewise functions in python?
def pwise (x): if x < 0: result='less than' elif x==0: result = 'equal' ... #more elif followed by else return result More on reddit.com
🌐 r/learnpython
9
1
December 11, 2015
Using CPLEX Piecewise Linear function
I’m trying to solve a MILP with an piecewise linear function in the cost function. At the moment, i’m using a binairy variable per linear piece wich is not the state of the art (see for example http://www.mit.edu/~jvielm… More on discourse.julialang.org
🌐 discourse.julialang.org
0
0
September 7, 2018
python - Fit points with a continuous, piecewise linear function with minimum number of points for each segment - Cross Validated
I have a set of two-dimensional data points that I want to fit with a continuous piecewise linear function with one break point. However, I want each of the two segments to be supported by a minimum More on stats.stackexchange.com
🌐 stats.stackexchange.com
Implement piecewise linear functions in python prophet
Hello, i have been trying out with the basic linear function und logistic function. But i wanted to improve the model a bit by using more sophisticated models like piecewise models. I researched fo... More on github.com
🌐 github.com
4
September 22, 2018
🌐
Readthedocs
piecewise-regression.readthedocs.io
piecewise-regression — piecewise-regression 1 documentation
The package is tested on Python 3.7, 3.8, 3.9 and 3.10. The package requires some x and y data to fit. You need to specify either a) some initial breakpoint guesses as start_values or b) how many breakpoints you want to fit as n_breakpoints (or both). Here is an elementary example, assuming we already have some data x and y: import piecewise_regression pw_fit = piecewise_regression.Fit(x, y, n_breakpoints=2) pw_fit.summary()
🌐
Reddit
reddit.com › r/learnpython › how to do piecewise functions in python?
r/learnpython on Reddit: How to do piecewise functions in python?
December 11, 2015 -

Hi guys,

I'm using numpy and plotly to graph piecewise functions. I previously used matlab. I need help to essentially translate matlab piecewise functions into something I can use in python. Here's what I had in matlab:

Constant1 = 5;
Constant2 = 10;

Formula1 = @(x,y) x*Constant1;
Formula2 = @(x,y) x*Constant2;

MainFormula = @(x,y) [Formula1(x,y)*(y<=5) + Formula2(x,y)*(y>5)];

So what this would essentially do is make 'MainFormula' equal to 'Formula1' for all values of y less than or equal to 5, and it would make 'MainFormula' equal to 'Formula2' for all values of y greater than 5.

I would really appreciate any help with this.

Thanks

Top answer
1 of 2
2
def pwise (x): if x < 0: result='less than' elif x==0: result = 'equal' ... #more elif followed by else return result
2 of 2
1
The direct translation would be this: constant1 = 5 constant2 = 10 formula1 = lambda x: x*constant1 formula2 = lambda x: x*constant2 main_formula = lambda x, y: formula1(x)*(y <= 5) + formula2(x)*(y > 5) Note that I am using python style conventions. All of your variable names could be used as-is, but for style reasons lowercase variable names separated by _ are usually used. Same with the spaces I added in x,y, y<=5, and y>5, they aren't required, just recommended for readability reasons. These style recommendations are found in pep8 , and can be checked automatically by a program of the same name. Further, you could do, for example lambda x, y: x*constant1, it doesn't hurt anything, but it is unnecessary and I think it makes the code less clear. However, assuming you are using numpy arrays (which you should be), it would be easier to do this: def formula(x, y, const1=5, const2=10, sep=5): x1 = x.copy() x1[y <= sep] *= const1 x1[y > sep] *= const2 return x You can then use formula in the exact same way as MainFormula. It will default to using 5 for the first constant and 10 for the second, and 5 for the value of y to use to differentiate the two, but you can change that by passing different values to the function, such as formula(x, y, sep=200), or formula(x, y, 50, 100). If you don't care about losing your original x, you can simplify this further: def formula(x, y, const1=5, const2=10, sep=5): x[y <= sep] *= const1 x[y > sep] *= const2 In this case, whatever array you pass to formula as x will be changed in-place, so nothing is returned. This will be considerably faster than any of the previous approaches when dealing with large datasets. You could even simplify this further by doing the y calculation in the function call if you wanted: def formula(x, isy, const1=5, const2=10): x[isy] *= const1 x[~isy] *= const2 And then call it like this: formula(x, y<=5) The final approach you could do is to handle x separately: def formula(isy, const1=5, const2=10): return isy*const1 + ~isy*const2 or: lambda isy: isy*constant1 + ~isy*constant2 And then call it like this: x1 = x*isy(y <=5)
🌐
PyPI
pypi.org › project › pwlf
pwlf · PyPI
A library for fitting continuous piecewise linear functions to data.
      » pip install pwlf
    
Published   Jul 26, 2025
Version   2.5.2
🌐
SciPy
docs.scipy.org › doc › scipy › tutorial › interpolate › splines_and_polynomials.html
Piecewise polynomials and splines — SciPy v1.17.0 Manual
B-splines are piecewise polynomials, represented as linear combinations of b-spline basis elements — which themselves are certain linear combinations of usual monomials, \(x^m\) with \(m=0, 1, \dots, k\). The properties of b-splines are well described in the literature (see, for example, ...
🌐
Mabouali
mabouali.com › 2024 › 02 › 04 › piecewise-linear-functions-part-i
Piecewise-Linear Functions: Part I – Moe’s Homepage
February 4, 2024 - We are going to divide this document in two parts. The first part, this document, we are going to discuss piecewise linear functions (PLFs) and how to implement one in Python.
Find elsewhere
🌐
FICO
fico.com › fico-xpress-optimization › docs › dms2020-03 › solver › optimizer › python › HTML › chModeling_sec_secPWL.html
Piecewise linear functions
The above example creates variables x, y, z1, and z2, then constrains z1 and z2 to be (piecewise linear) functions of x, to be used with y in other constraints and in the objective function. The Xpress Python interface provides another, more intuitive way of specifying such a function with the method xpress.pwl, which is passed a dictionary associating intervals (defined as tuples of two elements) with linear functions.
🌐
Songhuiming
songhuiming.github.io › pages › 2015 › 09 › 22 › piecewise-linear-function-and-the-explanation
piecewise linear function and the explanation — pydata: Huiming's learning notes
from scipy import optimize def piecewise_linear(x, x0, x1, b, k1, k2, k3): condlist = [x < x0, (x >= x0) & (x < x1), x >= x1] funclist = [lambda x: k1*x + b, lambda x: k1*x + b + k2*(x-x0), lambda x: k1*x + b + k2*(x-x0) + k3*(x - x1)] return np.piecewise(x, condlist, funclist) p , e = optimize.curve_fit(piecewise_linear, x, y) xd = np.linspace(-30, 30, 1000) plt.plot(x, y, "o") plt.plot(xd, piecewise_linear(xd, *p)) ... python, AI, LLM, AGI, AIG, GPT, data mining, sklearn, pytorch, career growth, linux, deep learning, leetcode, dynamic programming, flask, highcharts, sql, webCrawl, random walk, multiprocessing, data visualization, numpy, tensorflow, quant, statsmodels, pandas, docker, matplotlib, data minging, remote access, mysql, base, tweepy, bokeh, sentiment analysis, map, apply, apply_async, git, PyQt, cx_freeze, tkinter, pelican, spyre, shiny, R, re
🌐
Julia Programming Language
discourse.julialang.org › specific domains › optimization (mathematical)
Using CPLEX Piecewise Linear function - Optimization (Mathematical) - Julia Programming Language
September 7, 2018 - I’m trying to solve a MILP with an piecewise linear function in the cost function. At the moment, i’m using a binairy variable per linear piece wich is not the state of the art (see for example http://www.mit.edu/~jvielm…
🌐
GitHub
github.com › facebook › prophet › issues › 726
Implement piecewise linear functions in python prophet · Issue #726 · facebook/prophet
September 22, 2018 - Usage piecewise_linear(t, deltas, k, m, changepoint.ts) Arguments t Vector of times on which the function is evaluated.
Author   AntonioBlago
🌐
YouTube
youtube.com › caylie cincera
Part 2: IP with Piecewise Linear Functions in Python - YouTube
Part 2 of solving an IP with Piecewise Linear Functions in Python. Textbook: page 492 of "Operations Research: Applications and Algorithms" 4th edition by Wa...
Published   August 6, 2018
Views   526
🌐
GeeksforGeeks
geeksforgeeks.org › mathematics › piecewise-function
Piecewise Function | Graph, Domain, Range & Examples - GeeksforGeeks
July 23, 2025 - For example: If a function takes on any input and gives the output as 3. It can be represented mathematically as f(x) = 3. But in the case of the Piecewise function, it is defined by individual expressions for each interval.
🌐
Apmonitor
apmonitor.com › wiki › index.php › Apps › PiecewiseLinear
Piecewise Linear
Parameters ! independent variable x = 6.0 ! data points xp[1] = 1 yp[1] = 1 xp[2] = 2 yp[2] = 0 xp[3] = 3 yp[3] = 2 xp[4] = 3.5 yp[4] = 2.5 xp[5] = 4 yp[5] = 2.8 xp[6] = 5 yp[6] = 3 End Parameters Variables ! piece-wise linear segments x[1] <=xp[2] x[2:4] >xp[2:4], <=xp[3:5] x[5] >xp[5] !
🌐
YouTube
youtube.com › watch
Piecewise Linear Function IP in Python - YouTube
This video is a tutorial on how to solve a piecewise linear function as an IP in Python using the PuLp package. Textbook: page 494-495 of "Operations Researc...
Published   August 8, 2018
🌐
Gurobi
support.gurobi.com › hc › en-us › articles › 360013421331-How-do-I-model-piecewise-linear-functions
How do I model piecewise-linear functions? – Gurobi Help Center
How do I model a piecewise-linear function of more than one variable? How do I model logical and general expressions? Gwyneth Butera · August 27, 2025 02:02 Updated · Gurobi versions 9.0 and later include an interface for piecewise-linear constraints (e.g., Model.addGenConstrPWL() in Python).
🌐
NumPy
numpy.org › doc › stable › reference › generated › numpy.interp.html
numpy.interp — NumPy v2.4 Manual
Returns the one-dimensional piecewise linear interpolant to a function with given discrete data points (xp, fp), evaluated at x.