## Contour Plots

Contour plots are useful for visualizing the functional space and iteration history for 2D optimization problems. Optimization isn’t really necessary for 2D problems (you can just plot it and see the optimum), but studying 2D optimization problems is helpful for our learning because they can be easily visualized.

We will create contour plots for the simple function:

$z = 3(x - 2)^2 + (y+1)^2$

In both Python and Matlab this can be solved inline without any loops, but to represent what you would need to do with more complicated functions, we will make the computation of z a separate method.

## Matlab

First we create a method for computing z in a separate file called func.m.

function [z] = func(x, y)
z = 3*(x-2)^2 + (y+1)^2;
end


Next, we can create a contour plot across some chosen bounds and resolution


clear; close all;

% --- setup grid ---
nx = 200;  % number of points in x-direction
ny = 150;  % number of points in y-direction
x = linspace(-5, 5, nx);  % nx points equally spaced between -5...5
y = linspace(-6, 6, ny);  % ny points equally spaced between -6...6
[X, Y] = ndgrid(x, y);  % 2D array (matrix) of points across x and y
Z = zeros(nx, ny);  % initialize output of size (nx, ny)

% --- evaluate across grid ---
for i = 1:nx
for j = 1:ny
Z(i, j) = func(X(i, j), Y(i, j));
end
end

% --- contour plot ---
figure();  % start a new figure
contour(X, Y, Z, 50);  % using 50 contour lines.
xlabel('x');  % labels for axes
ylabel('y');


Notes:

• In Matlab you can use either meshgrid or ndgrid. meshgrid works exactly the same, except for the size of the array will be (ny, nx) (backwards from ndgrid) . This is intended to mimic the physical space where the columns go along the x-direction. I prefer ndgrid because I think it’s clearer to use x as the first index and y as the second.
• contourf is the same as contour, except for it creates filled colorbars.

## Python

The corresponding Python looks very similar. The main changes are:

• we can write the function (or any number of functions) in the same script.
• we need to explicitly import the modules we want to use (matlab imports everything automatically). In Matlab everything built-in is known so there won’t be name conflicts, but Python is expandable so to avoid name conflicts you need to explicitly import.
• use [] rather than () for indexing.
• no need for semicolons.

import numpy as np
import matplotlib.pyplot as plt

def func(x, y):
return 3*(x-2)**2 + (y+1)**2

# --- setup grid ---
nx = 200  # number of points in x-direction
ny = 150  # number of points in y-direction
x = np.linspace(-5, 5, nx)  # nx points equally spaced between -5...5
y = np.linspace(-6, 6, ny)  # ny points equally spaced between -6...6
X, Y = np.meshgrid(x, y, indexing='ij')  # 2D array (matrix) of points across x and y
Z = np.zeros((nx, ny))  # initialize output of size (nx, ny)

# --- evaluate across grid ---
for i in range(nx):
for j in range(ny):
Z[i, j] = func(X[i, j], Y[i, j])

# --- contour plot ---
plt.figure()  # start a new figure
plt.contour(X, Y, Z, 50)  # using 50 contour lines.