4
votes

I have 3 discriminant functions dividing 2D space into 3 regions. I would like to plot decision boundaries between these regions. I couldn't figure out how to do that using matplotlib meshgrid in python.

In case of 2 discriminant function, the process is simple. I calculate difference between function and contour plot for values of 0.

lin_param = (-5, 5, 100)
xx = np.linspace(*lin_param)
yy = np.linspace(*lin_param)

x, y = np.meshgrid(xx, yy)

z = g1(x, y) - g2(x, y)
cp = plt.contour(x, y, z, levels=[0], colors="k")

plt.scatter(0, 0)
plt.scatter(2, 2)
plt.show()

where g1 and g2 are multivariate gaussian distributions with mean (0, 0) and (2, 2). (Distributions are not important, I want to apply this to any discriminant function)

def pdf(x, y, mean, cov):
  var = multivariate_normal(mean=mean, cov=cov)
  pos = np.empty(x.shape + (2,))
  pos[:, :, 0] = x; pos[:, :, 1] = y
  return var.pdf(pos)

def g1(x, y):
  return pdf(x, y, mean=[0,0], cov=[[1,0],[0,1]])

def g2(x, y):
  return pdf(x, y, mean=[2,2], cov=[[1,0],[0,1]])

def g3(x, y):
  return pdf(x, y, mean=[-2,2], cov=[[1,0],[0,1]])

Decision boundaries between two classes

Here one side is negative and other side is positive. Values are all zero along decision boundary. Now I would to add third function g3 whose mean is at (-2, 2). Plotting resulting decision boundaries is not straightforward. I tried taking maximum 2 values of 3 function and assigning the difference of them as z value but couldn't achieve what I want.

What I would like to see is something similar to image below:

Desired output with 3 function

Is it possible achieve it with similar meshgrid-contour plot approach? I don't want to calculate the line explicitly.

Update

By using contourf method, regions can be filled with different color. However, drawing boundary lines is still problem.

Fill Plot

1
Have you seen this post? Especially this link in the first answer. - Thomas Kühn
@ThomasKühn Thank you. Yes I saw that but after your comment I inspected further and played with snippets posted there. That link shows how different regions can be painted (question is updated accordingly) but I had no luck drawing boundary lines. Although It is good enough for me, I won't close the question to see if anybody manages to draw boundaries. - Seljuk Gülcan

1 Answers

1
votes

I think I achieved desired output.

Instead of assigning difference between functions to z array, I assigned index of function having largest value. Then I used numbers between class labels (or function index) as levels parameter. For example, to draw boundary between class 0 and class 1, I added 0.5 to levels parameter.

z = np.array((g1(x, y), g2(x, y), g3(x, y)))
z = np.argmax(z, axis=0)
cp = plt.contour(x, y, z, colors="k", levels=[0.5, 1.5, 2.5])

enter image description here