Bivariate nonlinear regression using Python

Oscar Nieves
6 min readJan 19

In my previous article: https://oscarnieves100.medium.com/univariate-nonlinear-regression-in-python-deb91d1085cd, I discussed how to do nonlinear regression in Python for univariate data using the module scipy.optimize and the function curve_fit. Now, I will extend that to bivariate regression using the same technique.

Unbeknownst to some people, Python’s curve_fit function can also be used for bivariate regression, not just univariate. However, the way to do it is a bit tricky because of the way in which we need to restructure our data. In this article, I will show how to adapt your data to the right format in order to get this to work.

Setting up the data

Let us first import the necessary modules and define our data:

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
plt.style.use('seaborn-poster')

# Input data
x = np.array( [0.5, 1.0, 1.5] )
y = np.array( [0, 0.1, 0.2, 0.3, 0.4, 0.5] )

z1 = np.array([1.00120262, 0.98724237, 0.91583136, 0.78507447, 0.60688337,
0.39969003])
z2 = np.array([1.00094847, 0.97392313, 0.85439126, 0.67117433, 0.43412121,
0.22630919])
z3 = np.array([1.00001221, 0.96332839, 0.81539488, 0.58311224, 0.33212341,
0.1356312])

I have specifically chosen here two independent variables x and y, with x containing 3 elements and y 6, and also the “data” we have for those observables is split into 3 rows, each of which is stored in z1, z2 and z3 respectively, making up 18 observation points for 18 different combinations of x and y.

We could visualize this data by plotting a surface, but in cases like this where there aren’t that many datapoints I like to plot them in 2D as follows:

plt.figure(1)
plt.scatter(y,z1,color="black",s=50,label="data, x = " + str(x[0]))
plt.scatter(y,z2,color="blue",s=50,label="data, x = " + str(x[1]))
plt.scatter(y,z3,color="red",s=50,label="data, x = " + str(x[2]))
plt.xlabel(r"$y$",fontsize=30)
plt.ylabel(r"$z$",fontsize=30)
plt.legend(frameon=False, fontsize=20)
Figure 1: raw data

that way we have a unique plot for z1, z2 and z3 for each of our x values. This is also useful for visually inspecting the shape of z as we vary both x and y. As before, I will assume some kind of…

Oscar Nieves

I write stories about applied math, physics and engineering.