Matlab - How to get rid of edge artifact appearing around contour plot - matlab

I am facing a problem with the contourf function.
Here is my code, which is part of a gui (hence the handles):
contourLevels = (1:0.5:60);
axes(handles.firstcontouraxes);
contourf(Y,fliplr(X),z1, contourLevels,'edgecolor','none');
axis equal
colormap(cmap);
colorbar();
title('Paramater a plot');
set(gca,'TickDir','out','box','off');
Yielding the following plot:
As you can see, there is a red edge at the interface between the sample and air (air is when the value is 0 and appear white).
I suspect that contourf is trying to smooth my data, as the white area (air) is made of 0s and then we suddenly have relatively larger values at the sample-air interface.
Is it possible to remove this feature?

Related

Border of a scatter plot in Matlab: constructing it and colouring it

I would like your help to plot the border of a scatter in Matlab and fill it with a specified colour.
Let me firstly show you how the scatter looks like.
scatter(x,y)
Now, let me show you what I have tried to design the border.
k = boundary(x,y);
plot(x(k),y(k));
which produces this
This is not what I want. Firstly, the scatter is nicely convex and I don't understand why boundary produces that weird shape. Secondly, I want to colour with blue inside the border.
Could you kindly advise on how to proceed? Also, when building the border I would prefer not to rely on the convexity of the scatter, because in some of my real examples the scatter is not convex.
Boundary
There is no easy way to get the boundary of a non-convex shape without any information on what is expected. When should the boundary follow the convex hull and when should deviate from it?
Matlab function boundary is generic, made to work with arbitrary input coordinates. It has a 'shrink factor' parameter s that can be tuned between 0 (convex hull) and 1 (highly non-convex), depending on the expected result.
% Make some x,y data with a missing corner
[x,y]=meshgrid(1:20);
sel=~(x>15 & y<=5);
x=x(sel);y=y(sel);
% Compute boundary with several values for s
k=boundary([x,y]); %Default shrink factor : 0.5
k_convhull=boundary([x,y],0);
k_closest=boundary([x,y],1);
% Plot the boundary:
plot(x,y,'ok') %black circles
hold on
plot(x(k),y(k),'-r') %red line
plot(x(k_convhull),y(k_convhull),'-g') %green line
plot(x(k_closest),y(k_closest),'-b') %blue line
The re-entrant corner is still somewhat cut, even with the 'shrink factor' set to 1. If this does not suit you, you will need to make your own function to compute the coordinates of the border.
Plot a surface
You need to use a patch object there.
p=patch(x(k3),y(k3),[1 .8 .8]);
uistack(p,'bottom')
[1 .8 .8] is the RGB color of the patch surface (light pink)
uistack is there to move the patch below the other graphic objects, because it is not transparent. It will still cover the axes grid, if any. Another option is :
p=patch(x(k3),y(k3),[1 0 0],'FaceAlpha',.2);
Here, the patch will be plain red and drawn on top of other objects, but has 80% transparency set through the alpha channel (0 is fully transparent, 1 is solid color).
Beware, the patch object class has so many options that is somewhat complex to handle beyond basic use cases like this one.

Matlab: How can I control the color of a streamtube plot?

I am currently trying to plot 3D streamtubes. I want the tubes to be colored corresponding to their respective velocity (e.g. slow = blue, fast = red).
To be more exact, I have three 3D-matrices containing the velocity in x, y and z direction. The color of the streamtubes should be sqrt(vx^2+vy^2+vz^2). When using streamtube(x,y,z,vx,vy,vz,sx,sy,sz) the tubes are colored according to their z-coordinate which is useless because it's a 3D plot anyway.
Well this wasn't easy (it ought to be a builtin option), but by modifying the CData of each tube (they are each their own graphics object), you can achieve the desired result. Here's an example
load wind
[sx,sy,sz] = meshgrid(80,20:10:50,0:5:15);
h=streamtube(x,y,z,u,v,w,sx,sy,sz);
drawnow
view(3)
axis tight
shading interp;
This gives this picture:
but then doing this:
vel=sqrt(u.^2+v.^2+w.^2); %// calculate velocities
for i=1:length(h)
%// Modify the colour data of each tube
set(h(i),'CData',interp3(x,y,z,vel,get(h(i),'XData')...
,get(h(i),'YData'),get(h(i),'ZData'),'spline'))
end
drawnow
view(3)
axis tight
shading interp;
gives this result
NOTES:
1) I don't know if this is fully correct, I don't know how to test it
2) You have to interpolate the velocity data from the points where it's known onto the vertices of the streamtubes
3) I found the spline interpolation option to work best, but the other options might work better in other cases

Matlab: (1) Plotting multiple canvases, (2) holding them separately, (3) montage all

I've got 10 grayscale images. I'd like to plot a simple YELLOW line over each image separately, then show them all over one plot (montage style).
I tried to draw all images first, but that made plotting lines very tricky (X,Y axes weren't standard for plotting over each separate image).
I thought about burning the line over the image, but I don't have the computer vision toolkit (easy functions to do this), otherwise it seemed complicated to both convert the grayscale to color and get it to burn the image.
I thought I might be able to use the function newplot to create a temporary plot space for each image, draw the line with a simple plot(...) call, then save it and just montage(...) all the individual plots at the end.
Is this possible? I've never played with the function newplot or tried to loop through individual plots, saving them up for a call to montage(...) this way, but it seems like a logical/simple approach.
I finally worked it out with subplot, subimage, and plot, using subplot with the position arguments does what I want easily enough. Using subplot kept the axis relative to the subplot I was on so I could plot the line with a standard fplot/plot call. The trick was normalizing the position to percentages vs. thinking of it in terms of pixels.
here's some code demoing it:
% Loop through this code, each time moving the subplot by position
LOOP {
% calculate left & bottom position as percentages (0..1)
subplot( 'Position', [ left bottom (1/cols) (1/rows) ] );
hold on
% (1) Draw the image
subimage(tmpImg, [0 255]);
axis off;
% (2) Plot the line over the original image
F = #(x) polyval(p, x);
fplot(F, [1 dimX 1 dimY], '-y');
}

Axis commands changes TightInset property to zero

I use some things from this question get-rid-of-the-white-space-around-matlab-figures-pdf-output to get rid of the white space when saving figure plots and images. This works fine, but my problem is when I use commands like "axis square" or "axis image". Ivt sets TightInset property of corresponding axes to 0 in "y" direction. I mean when I use this:
inset=get(a,'TightInset');
second and fourth numbers in "inset" are always zero, even if I set title and x-label. So in the end I don't see plot titles and x-labels.
Can I fix it somehow? So far I do it manually by adding some suitable number, but it is not convenient.
EDIT: Some more code for example. It displays two histograms.
h=figure;
subplot(121)
bar(bins,histogram1,'hist');
axis square
title('Historgram 1');
xlabel('Intensity');
ylabel('Pixel count');
set(gca,'xlim',[0 1])
subplot(122)
bar(bins,histogram_out,'hist');
axis square
title('Histogram 2');
set(gca,'xlim',[0 1])
xlabel('Intensity');
ylabel('Pixel count');
and if I call
a=get(h,'Children');
for i=1:length(a)
inset=get(a(i),'TightInset');
%...some stuff here
end
those y-related numbers in inset are zeros. If I comment axis square and do this, then inset are correct and it does what I need.
As far as I know when you use 'TightInset' you'll get only the graph or image, axis will be removed. I downloaded a function from mathworks file exchange 'saveTightfigure.m' to solve a similar problem. But I did not needed axes. If you need axes may be you can edit limits set inside the function. I mean you can give a little more space at left and bottom for keeping the axes.

How do you draw different surfaces with the same color scale in MATLAB?

I'm trying to represent several surface plots* for which the scale differs a bit. Each surface plot is drawn in a separate subplot and/or figure.
Right now, I'm using the default color mapping, which automatically scales the whole range of the color map to my figure, i.e. the maximum of my surface is always red (in 'jet' color mode) regardless of the magnitude of this maximum.
I'd like the colormap to be consistent between the figures instead of spread between the min and max of each individual graph. That way, readers could appreciate the difference in scale of the surfaces just by looking at the color map.
Any idea on how to do this?
**Actually, in case it makes a difference, I'm plotting results of a surface fitting operation using the plot command as follows:*
[myfit, gof] = fit( ... );
plot(fit)
You should use the caxis function. For example, if one surface has a height from 0 to 5 and the other has a height from 0 to 10, doing the following for both plots:
caxis([0 10]);
will force them both to use the same color scale as the plot that covers the larger range. You can also call caxis with an axes handle as the first argument:
caxis(hAxes, [0 10]); % Sets the color scaling for hAxes
If not specified, caxis adjusts the color scaling of the axes that is current.
I recently answered this question in video form on my blog:
http://blogs.mathworks.com/videos/2009/03/27/setting-the-colormap-to-be-consistent-across-axes/