Matching Colormap and Colorbar - matlab

I'm running the following code
% x_start y_start x_end y_end concentration
A = [0 0 1 1 10
0 1 3 3 0.6
3 1 6 2 1.2];
cmap = jet(256);
con_min = 0;
con_max = 10;
ind_c = round((size(cmap,1)-1)*A(:,5)/(con_max-con_min))+1
figure;
set(gca,'ColorOrder',cmap(ind_c,:),'NextPlot','replacechildren');
plot([A(:,1) A(:,3)]',[A(:,2) A(:,4)]');
colorbar
However, my colorbar is not matching up with my colormap; it's using the default colorbar, and I'm running a custom colormap. How can I make it so that my colorbar shows the right values for my colormap?

Related

How to shade area and make it transparent between two lines in MATLAB?

I shaded the area between two lines, it's not very clean:
area(xData,[Y1(:) ,Y2(:)-Y1(:)]); hold on
colormap([1 1 1; 0 0 1]);
How to make it transparent too in MATLAB? So that it comes like:
ref:peltiertech.com
You can use the FaceAlpha property of the area object to set the transparency level:
xData = 1:7;
Y1 = [3 2 1 4 3 2 1];
Y2 = [8 6 9 8 7 5 6];
area(xData, Y2, 'EdgeColor',[0 .447 .741], 'FaceColor',[0.929 .694 .125], 'FaceAlpha',.3);
hold on
area(xData, Y1, 'EdgeColor',[0 .447 .741], 'FaceColor', [1 1 1]);
A cleaner approach is to use patch instead of area:
h = patch([xData xData(end:-1:1) xData(1)], [Y1 Y2(end:-1:1) Y1(1)], 'b');
set(h, 'EdgeColor',[0 .447 .741], 'FaceColor',[0.929 .694 .125], 'FaceAlpha',.3)

How to create a colormap based on value?

I have two vectors as follows:
x = 0:5:50;
sir_dB = [50 20 10 5 2 0 -5 -10 -20 -20 -20]
Where x denotes the distance on the x-axis and sir_dB the SNR. For this, I need to generate a color map for a grid of 50 x 60m something similar to this:
based on the value of sir_dB.
I tried the following:
sir_dB = [50 20 10 5 2 0 -5 -10 -20 -20 -20];
xrange = 0:50;
yrange = -30:30;
% create candidate set
[X, Y] = ndgrid(xrange, yrange); % grid of points with a spacing of 1.
candidate_set = [X(:), Y(:)];
test_pt = [0 30];
radius = 5;
% find which of these are within the radius of selected point:
idx = rangesearch(candidate_set, test_pt, radius );
neighborhood = candidate_set(idx{1}, :);
Once I have the neighbors at a radius of 5m, I need to color that part of the grid based on the sir_dB value for a corresponding x value.
I need to have the plot in such a way that for all values of sir_dB greater than 15, the grid should be colored green, yellow for y greater than 0 and red for y greater than -20.
Could someone provide me inputs of how to do this best?
Im not sure exactly what you want, but this should get you started with contourf. I increased the granularity of xrange and yrange to make the radius more smooth but you can change it back if you want.
x = 0:5:50;
sir_dB = [50 20 10 5 2 0 -5 -10 -20 -20 -20];
xrange = 0:0.1:50;
yrange = -30:0.1:30;
% create candidate set
[X, Y] = ndgrid(xrange, yrange); % grid of points with a spacing of 1.
candidate_set = [X(:), Y(:)];
test_pt = [0 30];
r = sqrt((test_pt(1)-X(:)).^2 + (test_pt(2)-Y(:)).^2);
idx = r>5;
snr = nan(size(X));
snr(idx) = interp1(x,sir_dB,X(idx),'linear');
% Some red, yellow, green colors
cmap = [0.8500 0.3250 0.0980;
0.9290 0.6940 0.1250;
0 0.7470 0.1245];
figure();
colormap(cmap);
contourf(X,Y,snr,[-20,0,15],'LineStyle','none');
Plotting the the contour plot alongside the original sir_dB we see that it lines up (assuming you want linear interpolation). If you don't want linear interpolation use 'prev' or 'next' for the interp1 method.
figure();
colormap(cmap);
subplot(2,1,1);
contourf(X,Y,snr,[-20,0,15],'LineStyle','none');
subplot(2,1,2);
plot([0,50],[-20,-20],'-r',[0,50],[0,0],'-y',[0,50],[15,15],'-g',x,sir_dB);
Here is another suggestion, to use imagesc for that. I nothed the changes in the code below with % ->:
x = 0:5:50;
sir_dB = [50 20 10 5 2 0 -5 -10 -20 -20 -20];
xrange = 0:50;
yrange = -30:30;
% create candidate set
[X, Y] = ndgrid(xrange, yrange); % grid of points with a spacing of 1.
% -> create a map for plotting
Signal_map = nan(size(Y));
candidate_set = [X(:), Y(:)];
test_pt = [10 20];
radius = 35;
% find which of these are within the radius of selected point:
idx = rangesearch(candidate_set,test_pt,radius);
neighborhood = candidate_set(idx{1}, :);
% -> calculate the distance form the test point:
D = pdist2(test_pt,neighborhood);
% -> convert the values to SNR color:
x_level = sum(x<D.',2);
x_level(x_level==0)=1;
ColorCode = sir_dB(x_level);
% -> apply the values to the map:
Signal_map(idx{1}) = ColorCode;
% -> plot the map:
imagesc(xrange,yrange,rot90(Signal_map,2))
axis xy
% -> apply custom color map for g-y-r:
cmap = [1 1 1 % white
1 0 0 % red
1 1 0 % yellow
0 1 0];% green
colormap(repelem(cmap,[1 20 15 35],1))
c = colorbar;
% -> scale the colorbar axis:
caxis([-21 50]);
c.Limits = [-20 50];
c.Label.String = 'SNR';
The result:

Contour colors don't correspond to color bar when a surf plot is added

Below is some code that recreates my problem as simplified as I can make it. It does a subplot with two plots, you'll notice the plot on the right (contour only) has the correct correlation between the contour colors and the color bar but when a surface is added (left plot) the colors no longer match up.
Notes:
I've tried contourslice but I get the same results. I've posted the code for that below too.
How far off the colors are seems to depend on the values of the contour data itself. If you replace my contour data with peaks, it works fine. However this does not solve the underlying problem.
Code using contour:
clear all; close all; clc
%define box coordinates
bx = [0 1 1 0 0;0 1 1 0 0]-.5;
by = [0 0 1 1 0;0 0 1 1 0]-.5;
bz = [0 0 0 0 0;1 1 1 1 1]-.5;
%make contour data
[x,y] = meshgrid(-1:.5:1,-1:.5:1);
con = (x.^2+y.^2);
figure(1)
subplot(1,2,1)
box = surf(bx,by,bz); %draw box
set(box,'FaceColor',[1 1 1],'FaceAlpha',1,'EdgeAlpha',0,'EdgeColor',[.5 .5 .5])
hold on
camlight(30,70)
contour(x,y,con) %draw contour
colorbar
axis([-1 1 -1 1 -1 1])
axis equal
subplot(1,2,2)
contour(x,y,con)
axis([-1 1 -1 1])
axis equal
colorbar
set(gcf,'outerposition',[150 150 800 300])
Code using contourslice instead of contour (same problem)
clear all; close all; clc
%define box coordinates
bx = [0 1 1 0 0;0 1 1 0 0]-.5;
by = [0 0 1 1 0;0 0 1 1 0]-.5;
bz = [0 0 0 0 0;1 1 1 1 1]-.5;
x = -1:.5:1;
y = x;
z = x;
%make contour data
[xg,yg,zg] = ndgrid(x,y,z);
V = 3-(xg.^2+yg.^2+zg.^2);
figure(1)
subplot(1,2,1)
box = surf(bx,by,bz); %draw box
set(box,'FaceColor',[1 1 1],'FaceAlpha',1,'EdgeAlpha',0,'EdgeColor',[.5 .5 .5])
hold on
camlight(30,70)
contourslice(x,y,z,V,[],[],0) %draw contour
colorbar
axis([-1 1 -1 1 -1 1])
axis equal
subplot(1,2,2)
contour(x,y,V(:,:,3))
axis([-1 1 -1 1])
axis equal
colorbar
set(gcf,'outerposition',[150 150 800 300])
Thanks for your help!
Just set the caxis property as you wish:
colorbar
caxis([0 2])
...
colorbar
caxis([0 2])
The problem was probably caused, because the surf plot changed the color determining values of your plot. By setting a fixed color axis you can avoid all misinterpretations.

Remove internal edges in 3D MATLAB plot using patch function

I am plotting a 3D object, say a cube, in MATLAB.
Node = [0 0 0; 1 0 0; 1 1 0; 0 1 0; 0 0 1; 1 0 1; 1 1 1; 0 1 1];
Elem = cell(1); Elem{1} = 1:8;
figure
for elm = 1:size(Elem,1)
X = Node(Elem{elm},:); K = convhulln(X); hold on;
patch('Faces',K,'Vertices',X,'FaceColor',rand(1,3),'FaceAlpha',1.0);
end
view(3); grid off; axis equal; cameramenu; axis off;
In the plot, how do I remove the internal diagonal lines? The plot should just show edges of cube. I am looking for a general solution which is applicable to any polyhedron.
the output of K=convhulln(X); is causing this, because convex hull will have triangular facets... (that's the default).
if instead you'd define K to be:
K= [1 2 3 4; ...
2 6 7 3; ...
4 3 7 8; ...
1 5 8 4; ...
1 2 6 5; ...
5 6 7 8];
You'll get it right.
Another option is to use geom3D from the FEX.

How can I display a 2D binary matrix as a black & white plot?

I have a 2D binary matrix that I want to display as a black and white plot. For example, let's say I have a 4-by-4 matrix as follows:
1 1 0 1
0 0 1 0
1 1 0 1
1 0 0 0
How can this be plotted as a black and white matrix? Some of my input binary matrices are of size 100-by-9, so I would ideally need a solution that generalizes to different sized matrices.
If you want to make a crossword-type plot as shown here (with grid lines and black and white squares) you can use the imagesc function, a gray colormap, and modify the axes properties like so:
mat = [1 1 0 1; 0 0 1 0; 1 1 0 1; 1 0 0 0]; % Your sample matrix
[r, c] = size(mat); % Get the matrix size
imagesc((1:c)+0.5, (1:r)+0.5, mat); % Plot the image
colormap(gray); % Use a gray colormap
axis equal % Make axes grid sizes equal
set(gca, 'XTick', 1:(c+1), 'YTick', 1:(r+1), ... % Change some axes properties
'XLim', [1 c+1], 'YLim', [1 r+1], ...
'GridLineStyle', '-', 'XGrid', 'on', 'YGrid', 'on');
And here's the image you should get:
I'm not sure if I got your question right, but you may try the image function, like this:
A = [ 1 1 0; 1 0 1; 1 1 1 ];
colormap([0 0 0; 1 1 1 ]);
image(A .* 255);
Try the spy function to start with perhaps.