plot a stacked bar chart in matlab that shows all the values - matlab

Hi I have the following code in Matlab
CC_monthly_thermal_demand = [495 500 500 195 210 100 70 65 85 265 320 430]';
AD_monthly_thermal_generation_250 = [193 193 193 193 193 193 193 193 193 193 193 193]';
figure;
bar(1:12,AD_monthly_thermal_generation_250)
hold on
bar(1:12,CC_monthly_thermal_demand,'r')
set(gca,'XTickLabel',{'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug',' Sep', 'Oct', 'Nov',' Dec'},'FontSize',18)
title('Seasonal Anaerobic Digestion (250kWe) Thermal Energy Supply to Demand - 2012','FontSize',22)
ylabel('Thermal Energy (MWhe)')
legend('250 kWth Supply','Thermal Energy Demand')
grid on
axis([0 13 0 600])
I am trying to plot a stacked bar chart that shows the colour of each variable for every bar. However, for the bars where the "AD_monthly_thermal_generation_250" is a lower value than the "CC_monthly_thermal_demand" the "AD_monthly_thermal_generation_250" colour is completely covered by the "CC_monthly_thermal_demand" and so I can't see these values. Is it possible to be able to see them?
Thank you

Combine the inputs together such that each series is a column, then use the option 'stack':
A = [495 500 500 195 210 100 70 65 85 265 320 430]';
B = [193 193 193 193 20 193 193 193 193 193 193 193]';
bar([B,A],'stacked')
EDIT addressing comment:
% Create random data and filler
A = randi(100,10,1);
B = randi(100,10,1);
mxA = max(A);
filler = mxA-A;
% Plot stacked bar chart
h = bar([A,filler,B],'stacked');
% Set the filler to transparent
set(h(2),'Face','none','Edge','none')
% Set y-labels
yticks = linspace(0,max(B),5) + mxA;
set(gca,'Ytick', [linspace(0,mxA,5) yticks(2:end)],'YtickL', [linspace(0,mxA,5) yticks(2:end)-mxA])

Related

How can I plot heatmap of Wi-Fi signal strength in a 2-D surface?

I've my dataset as follows (for instance):
strength = [-90 -90 -90 -90 -40 -20 -22.4 -45 -35 -41 -44 -55 -40 -75 -26]
X = [10 550 550 10 50 234 393 129 237 328 448 225 344 457 477]
Y = [10 10 410 410 293 210 202 132 130 142 141 272 268 274 200]
Here, strength is the received signal strength in dBm, X and Y are 2-D coordinates. I want to plot the heatmap of the signal strength at all the coordinate points.
My situation is similar to this question. However, I want to plot the received signal strength and in Matlab, as shown in the attached figure (because of picture quality). A solution in Matlab is found here, however, the code given in the link does not work. The Command Window of Matlab displays HeatMap object with 0 rows and 0 columns. The available code in Matlab is as follows:
strength = [-90 -90 -90 -90 -40 -20 -22.4 -45 -35 -41 -44 -55 -40 -75 -26]';
X = [10 550 550 10 50 234 393 129 237 328 448 225 344 457 477]';
Y = [10 10 410 410 293 210 202 132 130 142 141 272 268 274 200]';
strengthPercent = 2*(strength+100)/100;
picture = imread('https://www.mathworks.com/help/examples/thingspeak/win64/CreateHeatmapOverlayImageTSExample_02.png');
[height,width,depth] = size(picture);
OverlayImage=[];
F = scatteredInterpolant(Y, X, strengthPercent,'linear');
for i = 1:height-1
for j = 1:width-1
OverlayImage(i,j) = F(i,j);
end
end
alpha = (~isnan(OverlayImage))*0.6;
imshow(picture);
hold on
OverlayImage = imshow( OverlayImage );
caxis auto
colormap( OverlayImage.Parent, jet );
colorbar( OverlayImage.Parent );
set( OverlayImage, 'AlphaData', alpha );
Any suggestions, please!
Thank you.
You can use scatteredInterpolant as in the code you showed, just pair it with surf
F = scatteredInterpolant(X(:), Y(:), strength(:));
[XD, Yd] = meshgrid( 0:10:410, 0:10:550 );
Zd = F( XD, Yd );
surf( XD, Yd, Zd, 'EdgeColor', 'interp' );
view([0,90]); % view 3D plot from above
You can change the colormap to customise the appearance.
colormap( 'hot' );
colorbar();
You should be able to reduce the FaceAlpha of the surface to lay it over an image.

Changing the xticks for x axis in scatterplot

I'm plotting a scatter plot and would like to have the a-axis as entry named than index. My data is from MASS in R and looks like this
animals={'Mountain beaver';'Cow';'Grey wolf';'Goat';'Guinea pig';'Dipliodocus';'Asian elephant';'Donkey';'Horse';'Potar monkey';'Cat';'Giraffe';'Gorilla';'Human';'African elephant';'Triceratops';'Rhesus monkey';'Kangaroo';'Golden hamster';'Mouse';'Rabbit';'Sheep';'Jaguar';'Chimpanzee';'Rat';'Brachiosaurus';'Mole';'Pig'};
body=[1.35 465 36.33 27.66 1.04 11700 2547 187.1 521 10 3.3 529 207 62 6654 9400 6.8 35 0.12 0.023 2.5 55.5 100 52.16 0.28 87000 0.122 192];
brain=[8.1 423 119.5 115 5.5 50 4603 419 655 115 25.6 680 406 1320 5712 70 179 56 1 0.4 12.1 175 157 440 1.9 154.5 3 180];
% Plot
x=1:length(body);
scatter(x,body,'filled','d')
hold
scatter(x,brain,'filled')
legend('body', 'brain','location','east');
How could I amend the program so my scatterplot display animals in xticks with 45 degrees?
I think this is what you want:
% add these lines at the end of your code
set(gca,'XTickLabel',animals)
set(gca,'XTick',1:numel(animals));
xlim([0 numel(animals)+1]);
set(gca, 'XTickLabelRotation', 45);
which gives this:

Why doesn't the contourf function in Matlab use the highest value of the plotted data?

does anybody know why the function countourf doesn't use the color corresponding to the maximum value anywhere in the plot area?
if you try the code below, and then the command
get(h_colorbar,'YLim')
Matlab returns an upper limit which is not the highest element of the matrix (500), but a smaller number (475.9091).
As you can see from the commented lines in the code, I was able to change the upper/lower limits of the colorbar, but of course this doesn't solve the problem.
I'd like Matlab to actually use the highest values in my matrix of data; for instance, I'd like to see the point corresponding to (200,300) colored in the darkest red.
Xdata=[7 11 15 19 23 27 31 39 50 75 100 200];
Ydata=[50 100 140 150 200 300];
dataZ=[...
500 500 438 310 269 253 245 238 235 237 241 500 ...
500 414 291 259 248 244 241 239 239 250 274 500 ...
500 335 268 251 246 243 241 240 242 261 308 500 ...
500 323 264 250 245 243 241 241 243 265 319 500 ...
500 289 256 248 244 243 242 243 248 287 500 500 ...
360 264 250 245 244 243 244 247 261 376 500 500 ...
]';
% % % In matrix form
mdataZ=vec2mat(dataZ,length(Xdata));
[mXdata,mYdata]=meshgrid(Xdata,Ydata);
figure_5=figure;
set(gca,'FontName','Times New Roman', 'FontSize',16,'YColor','k')
hold on
box on
% % % set(gca,'CLim',[min(dataZ) max(dataZ)])
contourf(mXdata,mYdata,mdataZ,10)
scatter(19,140,50,'k')
h_colorbar=colorbar;
set(get(h_colorbar,'ylabel'),'string','Z','FontName','Times New Roman', 'FontSize',18)
set(h_colorbar,'FontName','Times New Roman','FontSize',16)
% % % set(h_colorbar,'YLim',[200 500],'YTick',[0:50:500])
% % % caxis([200 500])
axis([min(min(mXdata)),max(max(mXdata)),min(min(mYdata)),max(max(mYdata))])
xlabel('X','FontName','Times New Roman', 'FontSize',18)
ylabel('Y','FontName','Times New Roman', 'FontSize',18)
Any idea?
Thanks in advance!
contourf splits your data into n (10 for your case) levels. Unless you specify the levels they are chosen automatically by the function.
The highest level must be lower than the highest point in your data. Maybe it could be the same, I'm not sure how matlab treats values equal to a contour in this case. But if you leave it to automatic contour levels it will definitely be lower.
The individual data points are not plotted by the function, only the contour heights. Therefore, the value 500 is not in the colormap and the max is the height of the highest contour.
To solve this you can put a vector of contour values rather than n. Put the highest value close or equal to 500.
Following your suggestion, I replaced the line calling the countourf function.
Instead of the number of elements (10), I put linspace(min(dataZ),max(dataZ),10).
Interestingly, the minimum value used by contourf seems always to be the lowest element of the input matrix.
If you're curious, compare the previous code and the following:
new_figure=figure;
set(gca,'FontName','Times New Roman', 'FontSize',16,'YColor','k')
hold on
box on
contourf(mXdata,mYdata,mdataZ,linspace(min(dataZ),max(dataZ),10))
scatter(19,140,50,'k')
h_colorbar=colorbar;
set(get(h_colorbar,'ylabel'),'string','Z','FontName','Times New Roman', 'FontSize',18)
set(h_colorbar,'FontName','Times New Roman','FontSize',16)
axis([min(min(mXdata)),max(max(mXdata)),min(min(mYdata)),max(max(mYdata))])
xlabel('X','FontName','Times New Roman', 'FontSize',18)
ylabel('Y','FontName','Times New Roman', 'FontSize',18)

Conditional coloring of histogram graph in MATLAB

I have a histogram that I want conditional coloring in it with this rule :
Values that are upper than 50 have red bars and values lower than 50 have blue bars.
Suppose that we have this input matrix:
X = [32 64 32 12 56 76 65 44 89 87 78 56 96 90 86 95 100 65];
I want default bins of MATLAB and applying this coloring on X-axes (bins). I'm using GUIDE to design my GUI and this histogram is an axes in my GUI.
This is our normal graph. Bars with upper values than 50 should be red and bars with lower values than 50 should be green (X-axes). Bars with upper values than 50 should be red and ?
I think this does what you want (as per comments). The bar around 50 is split into the two colors. This is done by using a patch to change the color of part of that bar.
%// Data:
X = [32 64 32 12 56 76 65 44 89 87 78 56 96 90 86 95 100 65]; %// data values
D = 50; %// where to divide into two colors
%// Histogram plot:
[y n] = hist(X); %// y: values; n: bin centers
ind = n>50; %// bin centers: greater or smaller than D?
bar(n(ind), y(ind), 1, 'r'); %// for greater: use red
hold on %// keep graph, Or use hold(your_axis_handle, 'on')
bar(n(~ind), y(~ind), 1, 'b'); %// for smaller: use blue
[~, nd] = min(abs(n-D)); %// locate bar around D: it needs the two colors
patch([(n(nd-1)+n(nd))/2 D D (n(nd-1)+n(nd))/2], [0 0 y(nd) y(nd)], 'b');
%// take care of that bar with a suitable patch
X = [32 64 32 12 56 76 65 44 89 87 78 56 96 90 86 95 100 65];
then you create an histogram, but you are only going to use this to get the numbers of bins, the numbers of elements and positions:
[N,XX]=hist(X);
close all
and finally here is the code where you use the Number of elements (N) and the position (XX) of the previous hist and color them
figure;
hold on;
width=8;
for i=1:length(N)
h = bar(XX(i), N(i),8);
if XX(i)>50
col = 'r';
else
col = 'b';
end
set(h, 'FaceColor', col)
end
here you can consider using more than one if and then you can set multiple colors
cheers
First sort X:
X = [32 64 32 12 56 76 65 44 89 87 78 56 96 90 86 95 100 65];
sorted_X = sort(X)
sorted_X :
sorted_X =
Columns 1 through 14
12 32 32 44 56 56 64 65 65 76 78 86 87 89
Columns 15 through 18
90 95 96 100
Then split the data based on 50:
idx1 = find(sorted_X<=50,1,'last');
A = sorted_X(1:idx1);
B = sorted_X(idx1+1:end);
Display it as two different histograms.
hist(A);
hold on;
hist(B);
h = findobj(gca,’Type’,’patch’);
display(h)
set(h(1),’FaceColor’,’g’,’EdgeColor’,’k’);
set(h(2),’FaceColor’,’r’,’EdgeColor’,’k’);

How to arrange pixel address as order under certain condition?

I am currently doing map processing in matlab. Now i solved the maze and get the path of maze. Now i have turning point in map. But this address pixel are not in correct order. So i want to order the incorrect order of pixel address in to correct order.
INCORRECT ORDER:
shape(1).cen=[28;136];
shape(2).cen=[122;136];
shape(3).cen=[344;391];
shape(4).cen=[548;493];
shape(5).cen=[548;191];
shape(6).cen=[344;191];
shape(7).cen=[122;391];
CORRECT ORDR:
map(1).cen=[28;136];
map(2).cen=[122;136];
map(3).cen=[122;391];
map(4).cen=[344;391];
map(5).cen=[344;191];
map(6).cen=[548;191];
map(7).cen=[548;493];
My code is below:-
`map(1).cen=[28;136];
o=0; order=1;xflag=0;yflag=0;
k=length(shape); %indicates the total elements in shape.cen structure
for (j=1:k)
order=order+1; o=o+1;
if (j==1)
x=map(1).cen(1,1);
y=map(1).cen(2,1);
for(i=1:k)
xi=shape(i).cen(1,1);
yi=shape(i).cen(2,1);
if((x==xi)||(y==yi))
if(x==xi)
map(order).cen(1,1)=xi;
map(order).cen(2,1)=yi;
xflag=1;
break;
else
(y==yi)
map(order).cen(1,1)=xi;
map(order).cen(2,1)=yi;
yflag=1;
break;
end
end
end
end
x=map(o).cen(1,1);
y=map(o).cen(2,1);
for(i=1:k)
xi=shape(i).cen(1,1);
yi=shape(i).cen(2,1);
if(xflag==1)
if(y==yi)
map(order).cen(1,1)=xi;
map(order).cen(2,1)=yi;
xflag=0;
yflag=1;
break;
end
end
if (yflag==1)
if(x==xi)
map(order).cen(1,1)=xi;
map(order).cen(2,1)=yi;
xflag=1;
yflag=0;
break;
end
end
end
end
`
[shape.cen]' will give you the following array:
ans =
28 136
122 136
344 391
548 493
548 191
344 191
122 391
Now that it's a regular numerical array, you can use sortrows, like this.
map = sortrows([shape.cen]')
to get:
map =
28 136
122 136
122 391
344 191
344 391
548 191
548 493
If you don't want it as a numerical array, but a struct similar to shape, you can do:
[~, ID] = sortrows([shape.cen]')
map = shape(ID)'