Search code examples
matlabmatlab-figurecontour

Smooth edge contour plot


Hello
I want to represent data with 2 variables (latitude and longitude) in 2D format. The value is represented by color and the 2 variables as the 2 axis and I am using the contourf function to plot my data. All the data comes from a xlsx file and I put it in a matrix.

Locations = xlsread('Availability results.xlsx');
column_numberloc = 1; % Column in the locations file containing the number of the locations
column_latitude = 2; % Column in the locations file containing the latitude of the locations
column_longitude = 3; % Column in the locations file containing the longitude of the locations
column_availability = 4; % Column in the locations file containing the availability of the locations

min_latitude = min(Locations(:,column_latitude));
max_latitude = max(Locations(:,column_latitude));
min_longitude = min(Locations(:,column_longitude));
max_longitude = max(Locations(:,column_longitude));
max_availability = max(Locations(:,column_availability));
min_availability = min(Locations(:,column_availability));
longitude = Locations(:,column_longitude);
latitude = Locations(:,column_latitude);
Contour = zeros(23,17);

for numerofile=1:204
    [coord_x,coord_y] =transformation(Locations(numerofile,column_latitude),Locations(numerofile,column_longitude));
    Contour(coord_x,coord_y) = Locations(numerofile,column_availability);
end

for i=1:23
    for j=1:17
        if Contour(i,j) == 0
            Contour(i,j) = NaN;
        end
    end
end

cMap=jet(256);
figure(1);

x = linspace(min_longitude,max_longitude,17);
y = linspace(min_latitude,max_latitude,23);
newpoints = 100;

[xq,yq] = meshgrid(linspace(min(x),max(x),newpoints),linspace(min(y),max(y),newpoints ));
Contourq = interp2(x,y,Contour,xq,yq,'linear',max_availability);


[c,h]=contourf(xq,yq,Contourq,100);

%[c,h]=contourf(x,y,Contour,50);
set(h, 'edgecolor','none');
colormap(cMap);
cb=colorbar;
caxis([min_availability max_availability]);

The transformation function allows me to place all the data in the Contour matrix as it associate a longitude and a latitude to a row and a column.

I've putted a NaN for every data equal to zero to have a better look at my data and I obtained this : interpolation_linear

Which is nice but I wanted this data to be close to : Without interpolation

So, I decided to change the linear interpolation to a 'nearest' interpolation and I got this : interpolation_nearest

I can see more data but the contour plot isn't as smooth as with the linear interpolation.

I've seen many posts about how to make smooth contour plot (that's how I found the function 'interp2') but I think that my problem comes from the NaN data which prevent me from having a smooth contour plot at the edge between NaN values and the rest like the first image but with enough data like the third image.

My question is : Do you know how can I get a smooth edge contour plot with enough data thanks to the nearest interpolation but with a nice visual like the first image ?

Thank you very much


Solution

  • Since you are doing an interpolation on a square grid, you could directly display a 2D image with imagesc. The advantage is that you can access the AlphaData property of image objects, which can be used as a display mask.

    r=rand(50);            % random 50x50 array
    r(11:20,11:20)=NaN;    % some hole filled with NaN
    imagesc(r)             % show the image, with NaN considered as the lowest value in color scale
    imagesc(r,'AlphaData',~isnan(r)) % show the image, with NaN values set as fully transparent
    

    You may also then:

    • set a display mask first
    • replace zeros or NaN with some meaningful values (nearest non NaN value?)
    • interpolate with interp2, perhaps even with the 'cubic' parameter for improved smoothness
    • display only the meaningful part of the image thanks to the display mask set in AlphaData.