How to change bar graph style - matlab

I'm trying to create a bar graph, and set every bar a different style (lines, dots, circles and ext...).
In this example:
y = [2 2 3; 2 5 6; 2 8 9; 2 11 12];
x = [10; 20; 50; 90];
bar(x,y);
All 3 bars have the same style.
How can I change it and set 3 differents styles for the 3 bars ?

Use a handle output when calling bar
y = [2 2 3; 2 5 6; 2 8 9; 2 11 12];
x = [10; 20; 50; 90];
h = bar(x,y);
That gives an array h of bar objects (of length 3 in your example), and you can set their aspect independently. For example,
set(h(1), 'EdgeColor', 'r');
set(h(2), 'EdgeColor', 'g');
set(h(3), 'EdgeColor', 'b');
gives the following graph in R2015b (the aspect will vary in other versions).
Other properties you can change are 'BarWidth', 'LineStyle', etc. To see the list type get(h(1)).

I am adding some style changes to what #Luis given
y = [2 2 3; 2 5 6; 2 8 9; 2 11 12];
x = [10; 20; 50; 90];
h = bar(x,y);
set(h(1),'FaceColor', 'w','LineWidth', 1, 'LineStyle',':');
set(h(2),'FaceColor', 'w','LineWidth', 1, 'LineStyle','--');
set(h(3),'FaceColor', 'w','LineWidth', 1, 'LineStyle','-.');
'FaceColor', 'w' -- Makes the color of bar white
'LineWidth', 1 -- Width of the border line of bar
'LineStyle',':' -- Dotted line
'LineStyle','--' -- Dashed line
'LineStyle','-.' -- Dash-dot line
For different style for each bar set
figure
hold on;
y = [2 2 3; 0 0 0; 0 0 0;0 0 0 ];
x = [10; 20; 50; 90];
z=bar(x,y);
ylim([0 15]);
set(z,'FaceColor', 'w','LineWidth', 1, 'LineStyle',':');
y = [0 0 0; 2 5 6; 0 0 0;0 0 0 ];
x = [10; 20; 50; 90];
z1=bar(x,y);
set(z1,'FaceColor', 'w','LineWidth', 1, 'LineStyle','-.');
y = [0 0 0;0 0 0; 2 8 9; 0 0 0];
x = [10; 20; 50; 90];
z2=bar(x,y);
set(z2,'FaceColor', 'w','LineWidth', 1, 'LineStyle','-');
y = [0 0 0;0 0 0; 0 0 0; 2 11 12];
x = [10; 20; 50; 90];
z4=bar(x,y);
set(z4,'FaceColor', 'w','LineWidth', 1, 'LineStyle','--');
hold off;

Related

Reordering rows of several arrays in Matlab

Consider three matrices X1, X2, X3 in Matlab of dimension Nx(N-1) listing some integers among 0,1,...,10.
I want to reorder the elements in each row of X1, X2, X3 wrto X1, then X2 (if some elements of X1 are equal), then X3 (if some elements of X2 are equal) in ascending order.
Example 1
N=3;
X1=[3 8;
7 7;
2 1];
X2=[10 1;
10 9;
4 4];
X3=[1 1;
1 0;
1 0];
%I want to obtain
X1new=[3 8;
7 7;
1 2];
X2new=[10 1;
9 10;
4 4];
X3new=[1 1;
0 1;
0 1];
Example 2
N=4;
X1=[3 8 9;
7 6 6;
2 1 4;
4 4 4];
X2=[10 1 2;
9 10 10;
4 4 5;
5 5 2];
X3=[1 1 1;
0 0 1;
1 0 0;
0 0 0];
%I want to obtain
X1new=[3 8 9;
6 6 7;
1 2 4;
4 4 4];
X2new=[10 1 2;
10 10 9;
4 4 5;
2 5 5];
X3new=[1 1 1;
0 1 0;
0 1 0;
0 0 0];
This code does what I want. Could you suggest more efficient alternatives (if any) for cases in which size(Y,1) is large?
% 1) Create a 3d matrix Y of dimension Nx(N-1)x3
Y=NaN(N,N-1,3);
Y(:,:,1)=X1;
Y(:,:,2)=X2;
Y(:,:,3)=X3;
% 2) Reorder elements in each row (independently)
%wrto Y(:,:,1), then Y(:,:,2), then Y(:,:,3) in ascending order.
%Store everything in Ynew of dimension Nx(N-1)x3
Ynew = NaN(N,N-1,3);
for h = 1:size(Y,1),
Ynew (h,:,:) = sortrows(squeeze(Y(h,:,:)), [1 2 3]);
end
% 3) Create X1new, X2new, X3new
X1new=Ynew(:,:,1);
X2new=Ynew(:,:,2);
X3new=Ynew(:,:,3);
Since the numbers are between 0 and 10, you can easily combine the three matrices into one for the purposes of sorting (step 1); sort each row of the combined matrix and get the indices of that sorting (step 2); and from that build a linear index (step 3) which you can use into the original matrices (step 4):
M = 11; % Strict upper bound on possible values
Y = X1 + X2/M + X3/M^2; % STEP 1: combined matrix
[~, cols] = sort(Y, 2); % STEP 2: sort each row and get indices of sorting
ind = bsxfun(#plus, (1:size(X1,1)).', (cols-1)*size(X1,1)); % STEP 3: linear index
X1new = X1(ind); % STEP 4: result
X2new = X2(ind);
X3new = X3(ind);
sort(X,2) will do this. The 2 is to do it row-wise.
It can be done simply by using
'sort' command in Matlab
X1new = sort(X1,2);
X2new = sort(X2,2);
X3new = sort(X3,2);

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.

Plot square surface in Matlab

How to plot a square surface in Matlab?
More exactly I want to plot a square square with value 0.5 surface which is located at X:-1 to X=1 and Y:2.5 to 3.5.
I tried the following
[X,Y] = meshgrid(-3.5:.5:3.5);
Z = zeros(15);
Z(end-2:end,5:9) = 0.5;
surf(X,Y,Z);
This doesn't result in a perpendicular edge. How to archive that?
This is what the patch function is for.
Matlab documentation
so for your case:
X = [ -1 -1 1 1];
Y = [3.5 2.5 2.5 3.5];
Z = [0.5 0.5 0.5 0.5];
patch(X,Y,Z,'red')
view(45,45)
You need to provide multiple Z-values together with the same X, Y values. A small example:
>> [X, Y]= meshgrid([1,2,2,3,4], 1:2)
X =
1 2 2 3 4
1 2 2 3 4
Y =
1 1 1 1 1
2 2 2 2 2
>> Z = [0,0,1,1,0;0,0,1,1,0]
Z =
0 0 1 1 0
0 0 1 1 0
>> surf(X, Y, Z)
Yields this:
This should be the same in 2D, you just need to wrap you head around which X and Y values to duplicate and adjust the Z-Matrix accordingly.
I ended up with
figure;
hold on;
X = [ -2 -2 2 2];
Y = [2 4 4 2];
Z = [0 0 0 0];
patch(X,Y,Z,'blue');
X = [ -1 -1 1 1];
Y = [3.5 2.5 2.5 3.5];
Z = [0.5 0.5 0.5 0.5];
h = patch(X,Y,Z,'red');
X = [ -1 -1 1 1];
Y = [2.5 2.5 2.5 2.5];
Z = [0 0.5 0.5 0];
patch(X,Y,Z,'red');
X = [1, 1, 1, 1];
Y = [2.5 2.5 3.5 3.5];
Z = [0 0.5 0.5 0];
patch(X,Y,Z,'red');
view(45,30)
legend(h, 'F(u,v)')
xlabel('u')
ylabel('v')
zlabel('F(u,v)')

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 to get the bounding box of non-zero elements in MATLAB?

Let's say, I have a matrix (by imread) as following:
A = [0 0 1 0 0;
0 0 1 0 0;
0 1 1 1 0;
0 0 1 0 0;
0 0 0 0 0];
I would like to get the bounding box of non-zero elements as
BB = show_me_the_bounding_box(A);
BB = [1, 2, 4, 4]; % y0, x0, y1, x0
What function I should use to do that?
Use REGIONPROPS
stats = regionprops(A,'BoundingBox');
BB = stats.BoundingBox;
To get the result you want, please use:
[y,x] = ind2sub(size(A), find(A))
coord = [y, x]
[min(coord) max(coord)] % [1 2 4 4]
Note however that, with the correct conventions, the bounding box is:
[y,x] = ind2sub(size(A), find(A))
coord = [x, y]
mc = min(coord)-0.5
Mc = max(coord)+0.5
[mc Mc-mc] % [1.5 0.5 3 4]
which yields the same result as:
stats = regionprops(A, 'BoundingBox')
BB = stats.BoundingBox % [1.5 0.5 3 4]
The code can easily be adapted to 3D images, by using:
[y,x,z] = ind2sub(size(A), find(A));
coord = [x, y, z];
mc = min(coord)-0.5;
Mc = max(coord)+0.5;
[mc Mc-mc]