Polynomials: polyfit & poly1d
Reviewed & published by Brayan K
np.polyfit finds the least-squares polynomial that best fits a set of data points, and np.poly1d turns those coefficients into a reusable polynomial you can evaluate, plot, or solve.
Part of the free NumPy course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
You'll fit a trend line to noisy data, evaluate polynomials with poly1d and polyval, and find where a polynomial crosses zero with np.roots.
What You'll Learn in This Lesson
- Fit a line or curve with np.polyfit
- Read coefficients ordered high power to low
- Build a callable polynomial with np.poly1d
- Evaluate quickly with np.polyval
- Find zeros of a polynomial with np.roots
- Fit a trend line to noisy measurements
1 np.polyfit: Least-Squares Fitting
np.polyfit(x, y, deg) finds the polynomial of degree deg that minimizes the squared error against your data. It returns the coefficients ordered from the highest power down to the constant. A degree-1 fit gives [slope, intercept] — the classic trend line.
import numpy as np
x = np.array([0, 1, 2, 3, 4])
y = np.array([1, 3, 5, 7, 9]) # exactly y = 2x + 1
coeffs = np.polyfit(x, y, 1)
# coeffs = [2., 1.] -> slope 2, intercept 1import numpy as np
x = np.array([0, 1, 2, 3, 4])
y = np.array([1, 3, 5, 7, 9]) # y = 2x + 1
coeffs = np.polyfit(x, y, 1)
print(coeffs) # [2. 1.]
slope, intercept = coeffs
print("slope:", round(slope, 2)) # slope: 2.0
print("intercept:", round(intercept, 2)) # intercept: 1.0
# ✅ Expected output:
# [2. 1.]
# slope: 2.0
# intercept: 1.02 Evaluating with poly1d and polyval
Once you have coefficients, np.poly1d(coeffs) builds a callable polynomial object. Call it like a function, p(x), to evaluate at any point or array of points, and printing it shows the equation. For a one-off evaluation without keeping an object around, np.polyval(coeffs, x) does the same calculation directly.
coeffs = [2, 1] # 2x + 1
p = np.poly1d(coeffs)
p(10) # 21
p(np.array([0, 5, 10])) # [ 1 11 21]
np.polyval(coeffs, 10) # 21 (same result, no object)import numpy as np
coeffs = np.array([2, 1]) # 2x + 1
p = np.poly1d(coeffs)
# Printing shows the polynomial
print(p)
#
# 2 x + 1
# Evaluate at a single point and on an array
print(p(10)) # 21
print(p(np.array([0, 5, 10]))) # [ 1 11 21]
# polyval does the same thing in one call
print(np.polyval(coeffs, 10)) # 21
# ✅ Expected output:
#
# 2 x + 1
# 21
# [ 1 11 21]
# 213 Roots and Fitting a Curve to Noisy Data
np.roots(coeffs) finds where a polynomial equals zero. And the real power of polyfit shows up on noisy data: even when points scatter around a curve, polyfit recovers the underlying trend by minimizing squared error. A degree-2 fit, for instance, can capture a gentle bend that a straight line would miss.
# Roots of x^2 - 5x + 6 = 0
np.roots([1, -5, 6]) # [3. 2.]
# Fit a quadratic to noisy data
coeffs = np.polyfit(x, y_noisy, 2)
trend = np.poly1d(coeffs)import numpy as np
# Find the roots of x^2 - 5x + 6
roots = np.roots([1, -5, 6])
print(np.sort(roots)) # [2. 3.]
# Fit a trend line to noisy data
rng = np.random.default_rng(0)
x = np.linspace(0, 10, 50)
y_noisy = 3 * x + 2 + rng.normal(0, 2, size=x.size)
coeffs = np.polyfit(x, y_noisy, 1)
print("slope ~", round(coeffs[0], 1)) # slope ~ 3.2 (close to the true 3)
print("intercept ~", round(coeffs[1], 1)) # intercept ~ 1.1 (close to the true 2)
trend = np.poly1d(coeffs)
print("predicted at x=5:", round(float(trend(5)), 1)) # predicted at x=5: 17.3🎯 YOUR TURN: Fill in the Blank
Fit a straight line (degree 1) to these points by filling in the degree argument.
import numpy as np
x = np.array([0, 1, 2, 3])
y = np.array([5, 7, 9, 11]) # y = 2x + 5
# Fit a degree-1 (straight line) polynomial. Fill in the degree.
coeffs = np.polyfit(x, y, ___)
print(coeffs)
# Expected output:
# [2. 5.]Answer: 1. A degree of 1 fits a straight line, returning [slope, intercept] = [2., 5.].
! Common Errors (And How to Fix Them)
❌ Reading coefficients in the wrong order
polyfit returns highest power first, so treating coeffs[0] as the intercept is wrong:
slope = coeffs[1] # ❌ for a degree-1 fit this is the intercept✅ Fix: for a line, slope is first, intercept is last:
slope, intercept = coeffs # ✅ [slope, intercept]❌ Choosing too high a degree
A high-degree fit hugs the noise and oscillates wildly between points.
✅ Fix: start with degree 1 or 2 and only increase if the data clearly needs it.
❌ Forgetting poly1d coefficients are powers, not values
np.poly1d([2, 1]) means 2x + 1, not the points 2 and 1.
✅ Fix: print the object — print(np.poly1d([2, 1])) shows the equation it represents.
🎯 Mini Challenge: Predict Next Month's Sales
Fit a trend line to monthly sales, then use it to predict a future month.
import numpy as np
months = np.array([1, 2, 3, 4, 5, 6])
sales = np.array([100, 122, 138, 161, 180, 199])
# Fit a straight-line trend
coeffs = np.polyfit(months, sales, 1)
trend = np.poly1d(coeffs)
print("Slope (growth/month):", round(coeffs[0], 1)) # Slope (growth/month): 19.8
# Predict month 7
print("Predicted month 7:", round(float(trend(7)))) # Predicted month 7: 219
# ✅ Expected output:
# Slope (growth/month): 19.8
# Predicted month 7: 219❓ Frequently Asked Questions
Lesson complete — you can fit curves to data!
You can fit polynomials with np.polyfit, evaluate them with np.poly1d and np.polyval, find zeros with np.roots, and recover a trend from noisy measurements.
Practice quiz
What does np.polyfit(x, y, deg) return?
- The fitted y values
- The least-squares polynomial coefficients
- A plot
- The roots
Answer: The least-squares polynomial coefficients. polyfit returns the coefficients of the best-fit polynomial of the requested degree.
In what order does np.polyfit return coefficients?
- Lowest power first
- Random order
- Highest power first down to the constant
- Alphabetical
Answer: Highest power first down to the constant. Coefficients are ordered from the highest power down to the constant term.
For a degree-1 fit, what are the two coefficients?
- [slope, intercept]
- [intercept, slope]
- [x, y]
- [mean, std]
Answer: [slope, intercept]. A degree-1 fit returns [slope, intercept], highest power (slope) first.
What does np.poly1d(coeffs) create?
- A list of roots
- A NumPy array
- A plot object
- A callable polynomial object
Answer: A callable polynomial object. poly1d builds a callable polynomial you can evaluate, print, or find roots of.
Which evaluates a polynomial in one call without building an object?
- np.polyval(coeffs, x)
- np.poly1d(coeffs)
- np.polyfit(x, y)
- np.roots(coeffs)
Answer: np.polyval(coeffs, x). np.polyval(coeffs, x) computes the value directly without a reusable object.
What does np.roots([1, -5, 6]) return?
- [1, -5, 6]
- The values where the polynomial equals zero, e.g. 2 and 3
- The coefficients
- A single number
Answer: The values where the polynomial equals zero, e.g. 2 and 3. np.roots finds where the polynomial is zero; x^2 - 5x + 6 has roots 2 and 3.
What does np.poly1d([2, 1]) represent?
- The points 2 and 1
- The fraction 2/1
- The polynomial 2x + 1
- An error
Answer: The polynomial 2x + 1. The coefficients are powers: [2, 1] means 2x + 1, not the data points 2 and 1.
For a degree-2 fit, what does the result [a, b, c] mean?
- a*x**2 + b*x + c
- a + b + c
- c*x**2 + b*x + a
- Three separate roots
Answer: a*x**2 + b*x + c. Highest power first: [a, b, c] means a*x**2 + b*x + c.
Why avoid a very high polynomial degree on noisy data?
- It runs too slowly
- polyfit rejects it
- It overfits, wiggling through noise and generalizing badly
- It returns no coefficients
Answer: It overfits, wiggling through noise and generalizing badly. A high degree hugs the noise and oscillates; pick the lowest degree that captures the real shape.
Which degree fits a straight trend line?
- 3
- 1
- 0
- 2
Answer: 1. Degree 1 fits a straight line, returning [slope, intercept].
Continue this course
- Previous: Dates & Times with datetime64
- Next: Vectorizing Python Functions — Apply Python functions over arrays with vectorize and apply_along_axis
- Quick reference: NumPy cheat sheet
Frequently asked questions
What does np.polyfit return?
np.polyfit(x, y, deg) returns the coefficients of the least-squares best-fit polynomial of the requested degree, ordered from the highest power down to the constant term. For a degree-1 fit you get [slope, intercept]; for degree 2 you get [a, b, c] meaning a*x**2 + b*x + c. You then feed those coefficients to np.poly1d or np.polyval to evaluate the curve.
How do np.poly1d and np.polyval differ?
Both evaluate a polynomial from its coefficients. np.poly1d(coeffs) builds a callable polynomial object you can reuse, print in human-readable form, differentiate, or find roots of. np.polyval(coeffs, x) is a one-shot function that just computes the value at x. Use poly1d when you want an object to keep around, polyval for a quick evaluation.
What is np.roots used for?
np.roots(coeffs) finds all the values of x where the polynomial equals zero, including complex roots. Given the coefficients of x**2 - 5x + 6, it returns [3, 2]. It is the numerical way to solve a polynomial equation without doing the algebra by hand.
Is np.polyfit the modern recommended API?
np.polyfit, np.poly1d, and np.polyval are the classic and still extremely common interface, and they work perfectly well. NumPy also offers a newer, more numerically robust package under numpy.polynomial (for example numpy.polynomial.Polynomial.fit). For learning and most everyday fitting the legacy functions are clear and widely used, which is why this lesson focuses on them.