Search code examples
matlabplotmatlab-figurecontoursmoothing

Methods for smoothing contour lines


I have a database P with columns X, Y and Z:

x=0:1:50;
r=3.*rand(1,51);
P=[cos(x')+r',sin(x')+r',sin(x'+r').*cos(x')+r'];
P = sortrows(P,[1,2]);
N = 500;
xv = linspace(min(P(:,1)), max(P(:,1)), N);
yv = linspace(min(P(:,2)), max(P(:,2)), N);
[X,Y] = ndgrid(xv, yv);
Z = griddata(P(:,1), P(:,2), P(:,3), X, Y);
contourf(X, Y, Z, 35)

With the code above, I get the following subplot (right):

enter image description here

This "angularity" arises due to the addition of a vector r of random values ​​to the data. How to smooth out this angularity and make the graph smoother?

I tried to increase N to 2500. It did not give a significant result (in fact, it stopped changing significantly after N=1500).


Solution

  • To smooth your 2D data you can use a 2D convolution, with the operator conv2

    With your example data:

    n = 10 ;
    kernel = ones(n)/n.^2 ;
    Zs = conv2(Z, kernel,'same') ;
    
    contourf(X, Y, Zs, 35) ;
    title(sprintf('Filter size: n=%d',n))
    

    will yield:

    smoothed n=10


    You have to adjust the filter size (the parameter n) until you get the desired result. For example with n=20 you will get:

    smoothed n=20

    And for n=50:

    smoothed n=50


    A few things to keep in mind:

    • Since you have NaN in your matrix Z, the filtering will erode the border of you initial domain. The stronger the filtering/smoothing (higher n), the more erosion you will notice until very little non-NaN data is left .

    • For it to be a smoothing operation and not another transform or filtering, the convolution kernel has to be built so (i) all the elements are of equal value, and (ii) the total sum of the elements should be 1.

    A quick demonstration with n=2:

    >> n=2
    n =
         2
    >> kernel = ones(n)/n.^2
    kernel =
                          0.25                      0.25
                          0.25                      0.25
    >> sum(sum(kernel))
    ans =
         1