1
votes

I am very new to Octave and Matlab,

I am trying to plot a surface plot for Gaussian distribution to visualize anomaly detection using two features (x axis and y axis) of a data set and the Gaussian value (z axis).

   X1           X2       Z(the Gaussian value )  

0.00000       3.0000          0.0153130  
2.00000       2.8000          0.0457589
2.20000       3.0000          0.0550785
2.30000       2.0000          0.0163526
2.40000       2.2000          0.0252592
2.70000       3.5000          0.0615501
2.70000       4.2000          0.0259381
2.90000       3.0000          0.0695891
4.10000       1.6000          0.0088349
4.40000       3.5000          0.0812291
4.40000       4.5000          0.0179289
4.80000       3.2000          0.0886546
5.90000       3.0000          0.0734376
6.30000       3.0000          0.0658523
5.90000       4.0000          0.0407246
6.40000       4.0000          0.0353848
6.20000       3.0000          0.0678455
6.30000       3.6000          0.0576709
8.20000       3.8000          0.0195292
10.00000      2.7000          0.0054764

Below given is a plot similar to which I desire:

enter image description here

My Attempt:

I tried creating a mesh-grid for each dimension and did a surfplot on the matrix, but It didnt work. It gave me a weird plot, Which is shown below

[X1,Y1]=meshgrid(x1',x2');
[Z]=meshgrid(z');
surf (X,Y,Z)

enter image description here

I'd be glad If somebody help me get the graph correctly

Thanks you :)

1

1 Answers

1
votes

I'm assuming you want to interpolate between the given 2D co-ordinates to try and create a Gaussian surface. What you need to use is griddata (Octave doc) (MATLAB doc), where you specify your (x,y,z) points, then specify the 2D co-ordinates that form the output surface that you want. To do this, you can use a combination of meshgrid (Octave doc) (MATLAB doc) and linspace (Octave doc) (MATLAB doc) to help you generate those points.

We can use linspace to generate a linear set of points for each axis from the minimum to the maximum of each axis. By default linspace will generate 100 points between a given minimum and maximum, so let's stick with those. After, use meshgrid to generate the final grid of 2D points you want your Gaussian surface to occupy. You then use griddata using the input (x,y,z) points as well as the final grid of 2D points generated from meshgrid to generate your final surface. Because of the "curviness" of the Gaussian curve, I would specify the cubic flag to perform bicubic interpolation in the regions outside of your control points that define your Gaussian curve. griddata by default uses bilinear interpolation, but let's override and use bicubic instead.

Without further ado, assuming X1, X2 and Z are all vectors loaded in your workspace, this is the code to interpolate and generate the surface:

limitsX = linspace(min(X1), max(X1));
limitsY = linspace(min(X2), max(X2));
[X1out,X2out] = meshgrid(limitsX, limitsY);
Zout = griddata(X1, X2, Z, X1out, X2out, 'cubic');
surf(X1out, X2out, Zout);
title('Interpolated Gaussian Surface');
xlabel('X1');
ylabel('X2');
zlabel('Z');

This is the surface I get:

enter image description here

This doesn't resemble the actual Gaussian curve (... more like a botched raised tent), and the reason why is because the data you have sampled from your Gaussian distribution is too sparse and the control points are far away from each other. For the points that are in between the control points, you have to interpolate and the interpolation won't be as accurate as the actual points coming from the Gaussian distribution itself.

If you're serious about building a Gaussian surface, you should actually generate the points from the mathematical definition of the Gaussian, then the surface plot will certainly look accurate.