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

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 1
import 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.0

2 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]
# 21

3 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

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.