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.
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.
colorbar(); % add a colorbar
xlabel('x'); % labels for axes
ylabel('y');
Notes:
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.The corresponding Python looks very similar. The main changes are:
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.
plt.colorbar() # add a colorbar
plt.xlabel('x') # labels for axes
plt.ylabel('y')
plt.show() # show plot
Notes: