Visualizing a segmented toroidal surface in Matlab - matlab

I have gone through the related solutions to "Visualizing a toroidal surface in Matlab" but my problem is a little different.I want to be able to visualize segmented toroidal surfaces arranged with vertices attached to each other.Just like a stuck of semi circles with axis along the y-axis in the x-y plane.
`th = linspace( pi/2, -pi/2, 100);
R = 1; %or whatever radius you want
x = -R*cos(th) + 4;
y = -R*sin(th) + 7;
plot(x,y); axis equal;
hold on
x = -R*cos(th) + 4;
y = -R*sin(th) + 9;
plot(x,y); axis equal;
hold on
x = -R*cos(th) + 4;
y = -R*sin(th) + 11;
plot(x,y); axis equal;
hold on
x = -R*cos(th) + 4;
y = -R*sin(th) + 5;
plot(x,y); axis equal
hold on
x = -R*cos(th) + 4;
y = -R*sin(th) + 3;
plot(x,y); axis equal
hold on
x = -R*cos(th) + 4;
y = -R*sin(th) + 1;
plot(x,y); axis equal
hold on
x = -R*cos(th) + 4;
y = -R*sin(th) -1;
plot(x,y); axis equal
hold on
x = -R*cos(th) + 4;
y = -R*sin(th) -3;
plot(x,y); axis equal
hold on
x = -R*cos(th) + 4;
y = -R*sin(th) -5;
plot(x,y); axis equal
hold on
x = -R*cos(th) + 4;
y = -R*sin(th) -11;
plot(x,y); axis equal
hold on
x = -R*cos(th) + 4;
y = -R*sin(th) -9;
plot(x,y); axis equal
hold on
x = -R*cos(th) + 4;
y = -R*sin(th) -7;`
plot(x,y); axis equal`

Related

Flip array data values - Matlab

How can I flip the array data values (based on Y values) so when I am plotting it will be like a mirror plot? (instead of looking like a “mountain” it will look like a “valley”)
Code:
clc
clear
close all
y = [4 5 6 9 10 20 22 25 22 20 15 10 0];
x = 0:12;
data = rot90(cat(1, x, y));
flipData = flip(data);
figure('Name','Data','NumberTitle','off');
plot(data(:,1),data(:,2),'r','LineWidth',2);
figure('Name','Flip Data','NumberTitle','off');
plot(flipData(:,1),flipData(:,2),'r','LineWidth',2);
You can plot max(y) - y:
y2 = max(y) - y;
plot(x, y2, 'r', 'LineWidth', 2);
You can reverse the direction of the axis, so that your graph is upside down, but Y-values are still correct.
y = [4 5 6 9 10 20 22 25 22 20 15 10 0];
x = 0:12;
data = rot90(cat(1, x, y));
figure('Name','Data','NumberTitle','off');
plot(data(:,1),data(:,2),'r','LineWidth',2);
figure('Name','max(y) - y','NumberTitle','off');
y2 = max(y) - y;
plot(x, y2, 'r', 'LineWidth', 2);
figure('Name','ax.YDir reverse','NumberTitle','off');
plot(data(:,1),data(:,2),'r','LineWidth',2);
ax = gca;
ax.YDir = 'reverse';

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:

Vectorize plotting multiple lines with different colors in MATLAB?

Is there a way to vectorize/accelerate the task of plotting multiple lines with different colors?
The working-but-slow approach is
X = [1 2; 3 4];
Y = [2 -4; 5 2];
figure;
hold on;
colors = [1 0 0; 0 1 0];
for idx = 1:size(X, 2)
l = plot(X(:, idx), Y(:, idx), 'Color', colors(idx, :));
end
hold off;
I tried
X = [1 2; 3 4];
Y = [2 -4; 5 2];
figure;
plot(X, Y, 'Color', [1 0 0; 0 1 0]);
but no luck.
This is probably too hacky to be a useful replacement of the loop, but here it goes:
set(gca, 'ColorOrder', [1 0 0; 0 1 0], 'NextPlot', 'add')
plot(X, Y);
The 'ColorOrder' property contains the colors to be used by default for new plots. Setting 'NextPlot' to 'add' seems to be necessary so that the call to plot doesn't reset 'ColorOrder' to its default value.
Tested on R2015b.

How to rewrite this Matlab 2014 code with axis-subplots to 2016?

Code which I wrote for Matlab 2014 but which I want to rewrite it to Matlab 2016 such that it becomes more compact, since it is extranous now
hFig3=figure('Units', 'inches');
hax3_b1=axes('Parent', hFig3);
hax3_b2=axes('Parent', hFig3);
hax3_b3=axes('Parent', hFig3);
hax3_b4=axes('Parent', hFig3);
b1=subplot(2,2,1, hax3_b1);
b2=subplot(2,2,2, hax3_b2);
b3=subplot(2,2,3, hax3_b3);
b4=subplot(2,2,4, hax3_b4);
% Example of common expression
set([b1 b2], 'Units', 'inches'); % http://stackoverflow.com/a/39817473/54964
u=0:0.1:1; y=sin(u); C = [0 2 4 6; 8 10 12 14; 16 18 20 22];
imagesc(b1, u, y, C);
hold on;
plot(b2, u');
histogram(b3, u');
histogram(b4, u);
hold off;
drawnow;
Output is ok
OS: Debian 8.5 64 bit
MATLAB: 2014 but want to convert to 2016
You can simply write:
figure('Units','inches');
b1 = subplot(2,2,1);
b2 = subplot(2,2,2);
b3 = subplot(2,2,3);
b4 = subplot(2,2,4);
or preferably, if you want to have an array of the axes:
figure('Units','inches');
b(1) = subplot(2,2,1);
b(2) = subplot(2,2,2);
b(3) = subplot(2,2,3);
b(4) = subplot(2,2,4);
or use a simple for loop:
figure('Units','inches');
b(1:4) = axes;
for k = 1:numel(b)
b(k) = subplot(2,2,k);
end
In any option you choose there is no need for all the axes commands.
Here is all your 'demo' code:
b(1:4) = axes;
for k = 1:numel(b)
b(k) = subplot(2,2,k);
end
set(b(1:2), 'Units', 'inches');
u=0:0.1:1; y=sin(u); C = [0 2 4 6; 8 10 12 14; 16 18 20 22];
imagesc(b(1), u, y, C);
plot(b(2), u');
histogram(b(3), u');
histogram(b(4), u);
There might be no real need also in the figure command, it depends on what do with it.
If you're just looking for shorter you can eliminate most of the stuff at the beginning. You don't need the figure but I keep it as a matter of habit.
fh = figure;
x = 1:4;
b = arrayfun(#(y) subplot(2,2,y), x, 'UniformOutput',0);
b{1}.Units = 'inches';
b{2}.Units = 'inches';
u=0:0.1:1; y=sin(u); C = [0 2 4 6; 8 10 12 14; 16 18 20 22];
imagesc(b{1}, u, y, C);
plot(b{2}, u');
histogram(b{3}, u');
histogram(b{4}, u);

Matlab circle radius duplication

I'm new to Matlab can anyone explain why the circle is measuring as 10 on the graph double to the radius. I expected it to be 5 matching the radius
xCenter = 5;
yCenter = 5;
theta = 0 : 0.01 : 2*pi;
radius = 5;
x = radius * cos(theta) + xCenter;
y = radius * sin(theta) + yCenter;
plot(x, y);
axis square;
xlim([0 10]);
ylim([0 10]);
grid on;
Thanks
If you want the circle to reach 5 on the x and y axes, then it should be centered at the origin.