how to add data labels for bar graph in matlab - matlab

For example (code):
x = [3 6 2 9 5 1];
bar(x)
for this I need to add data labels on top of the each bar.
I know that I have to use TEXT keyword, but I'm not getting how to implement it.

Here is a simple solution with text:
x = [3 6 2 9 5 1];
bar(x)
ylim([0 max(x)*1.2])
text(1:numel(x),x+0.5,num2cell(x))

Based off this answer:
data = [3 6 2 9 5 1];
figure; %// Create new figure
hbar = bar(data); %// Create bar plot
%// Get the data for all the bars that were plotted
x = get(hbar,'XData');
y = get(hbar,'YData');
ygap = 0.1; %// Specify vertical gap between the bar and label
ylimits = get(gca,'YLim');
%// The following two lines have minor tweaks from the original answer
set(gca,'YLim',[ylimits(1),ylimits(2)+0.2*max(y)]);
labels = cellstr(num2str(data')) %//'
for i = 1:length(x) %// Loop over each bar
xpos = x(i); %// Set x position for the text label
ypos = y(i) + ygap; %// Set y position, including gap
htext = text(xpos,ypos,labels{i}); %// Add text label
set(htext,'VerticalAlignment','bottom', 'HorizontalAlignment','center')
end

After some attempts I have found the solution. Do the following:
y = Data;
for b = 1 : 10
BarPlot(b) = bar(b, y(b), 'BarWidth', 0.9); % actual plot
set(BarPlot(b), 'FaceColor', 'blue'); %Apply color
barTopper = sprintf('%.1f%s', y(b)*100,'%'); % Place text on top
text(b-0.5, y(b)+0.01, barTopper, 'FontSize', barFontSize); % position the text
hold on;
end
Let me know if it works.

Related

How to plot errorbars in a grouped bar?

I want to plot errorbar in my grouped bars. I wrote following code
x = categorical({'a', 'b', 'c', 'd', 'e'});
y = [6816,7215; 5824,6180; 4860,5200; 3860,4206; 2838,3185];
errlow = [238,337;270,355;303,297;291,340;259,382];
errhigh = [231,264;225,337;153,171;185,286;167,247];
b = bar(x,y);
hold on
xtips1 = b(1).XEndPoints;
ytips1 = b(1).YEndPoints;
er = errorbar(xtips1, ytips1, errlow(:,1), errhigh(:,1));
er.Color = [0 0 0];
er.LineStyle = 'none';
hold on
xtips2 = b(2).XEndPoints;
ytips2 = b(2).YEndPoints;
er2 = errorbar(xtips2, ytips2, errlow(:,2), errhigh(:,2));
er2.Color = [0 0 0];
er2.LineStyle = 'none';
hold off
ylim([2400 7600]);
Errorbars are displaying into the graph. Please have a look, they are straight over a, b, c, d and e but not on the bar as shown in the figure.
I want them on the associated bars ('GREEN' marked error should be on right bar whereas 'RED' marked error should be on left bar) as presented in the figure. How do I do that?
Thanks in advance!
This is the answer provided by the MathWorks Support Team, as posted on MATLAB Answers (with the exception of some minor modifications).
The ability to specify that the errorbar function should display the error bars inside the patches is not available in MATLAB.
There are two work arounds for this limitation, usage of which depends on the release of MATLAB that you are using.
If you are using R2019a or earlier releases, find the center of each bar and pass this data into errorbar with the respective error values.
If you are using R2019b or later releases, retrieve the x coordinate of each bar using the XEndPoints property and pass this data into errorbar.
The following is an example of the above:
% Example data
model_series = [10 40 50 60; 20 50 60 70; 30 60 80 90];
model_error = [1 4 8 6; 2 5 9 12; 3 6 10 13];
b = bar(model_series, 'grouped');
For MATLAB R2019a or earlier releases:
hold on
% Find the number of groups and the number of bars in each group
ngroups = size(model_series, 1);
nbars = size(model_series, 2);
% Calculate the width for each bar group
groupwidth = min(0.8, nbars/(nbars + 1.5));
% Set the position of each error bar in the centre of the main bar
% Based on barweb.m by Bolu Ajiboye from MATLAB File Exchange
for i = 1:nbars
% Calculate center of each bar
x = (1:ngroups) - groupwidth/2 + (2*i-1) * groupwidth / (2*nbars);
errorbar(x, model_series(:,i), model_error(:,i), 'k', 'linestyle', 'none');
end
hold off
For MATLAB 2019b or later releases:
hold on
% Calculate the number of bars in each group
nbars = size(model_series, 2);
% Get the x coordinate of the bars
x = [];
for i = 1:nbars
x = [x ; b(i).XEndPoints];
end
% Plot the errorbars
errorbar(x',model_series,model_error,'k','linestyle','none')'
hold off

YTickLabel will be shown with some specified value (not show all) in Matlab

I have code and the result as below:
%% How to plot each matrix in a cell in 3d plot(1 matrix with 1 color) ?
% Generate Sample data cell A(1x10 cell array)
clear; clc;
A = cell(1,10); % cell A(1x10 cell array)
for kk = 1:numel(A)
z = 10*rand()+(0:pi/50:10*rand()*pi)';
x = 10*rand()*sin(z);
y = 10*rand()*cos(z);
A{kk} = [x,y,z];
end
A_6 = A(1:6); % generate a cell with the first 6 matrices in "A" cell array
% The numer "6" can be changed to be any number which you want to plot them by colormap
newA = vertcat(A_6{:}); %Concatenating all matrices inside A vertically
numcolors = numel(A_6); %Number of matrices equals number of colors
colourRGB = hsv(numcolors); %Generating colours to be used using hsv colormap
colourtimes = cellfun(#(x) size(x,1),A_6);%Determining num of times each colour will be used
colourind = zeros(size(newA,1),1); %Zero matrix with length equals num of points
colourind([1 cumsum(colourtimes(1:end-1))+1]) = 1;
colourind = cumsum(colourind); %Linear indices of colours for newA
scatter3(newA(:,1), newA(:,2), newA(:,3), [], colourRGB(colourind,:),'filled');
%if you want to specify the size of the circles, use the following line instead:
% scatter3(newA(:,1), newA(:,2), newA(:,3), colourind , colourRGB(colourind,:),'filled');
grid on;
view(3); %view in 3d plane
colormap(colourRGB); %using the custom colormap of the colors we used
%Adjusting the position of the colorbar ticks
caxis([1 numcolors]);
colorbar('YTick',[1+0.5*(numcolors-1)/numcolors:(numcolors-1)/numcolors:numcolors],'YTickLabel', num2str([1:numcolors]'), 'YLim', [1 numcolors]);
I have the image like this:
How can I shown "YTickLabel" with some specified value (not show all) as below figure?
Taking the code from your comment to the previous answer:
h = colorbar('YTick',[1:numcolors],'YTickLabel', num2str([1:numcolors]'), 'YLim', [1 numcolors]); set(h, 'Ticklabels', {1 [] 3 [] 5 6}); set(h, 'Ticks', {1 3 5 6});
You are now setting 6 tick labels for only 4 ticks. If set the ticks to the correct values, then the auto-generated tick labels will be what you want.
Try the following:
h = colorbar('YTick',[1:numcolors],'YTickLabel', num2str([1:numcolors]'), 'YLim', [1 numcolors]);
set(h, 'Ticks', {1 3 5 6});
To remove some ticks with their labels, just set the 'YTick' property of the colorbar accordingly. That is, replace your last line by something like:
colorbar('YTick', [1 3 5 6], 'YLim', [1 numcolors])

Re-scaling X axis in imagesc plot in Matlab

I have written the following code in Matlab to show different shades of color red. How can I re-scale all x-axis in sub-plots to 0-1?
% create a custome color map
map = zeros(11,3);
reds = 0:0.1:1;
map(:,1) = reds(:);
colormap(map);
figure(1)
depth = [1 2 3 4];
num_depth = length(depth);
for index = 1: num_depth
subplot(num_depth,1,index);
step = 1/(2^depth(index)-1);
A = 0:step:1;
imagesc(A);
axis equal
set(gca,'ytick',[])
end
However, imagesc(x,y,C) could specifies the image location. Use x and y to specify the locations of the corners corresponding to C(1,1) and C(m,n).
% create a custome color map
map = zeros(11,3);
reds = 0:0.1:1;
map(:,1) = reds(:);
colormap(map);
figure(1)
depth = [1 2 3 4];
num_depth = length(depth);
for index = 1: num_depth
subplot(num_depth,1,index);
step = 1/(2^depth(index)-1);
A = 0:step:1;
imagesc(0:1,0:1,A)
axis([0 1 0 1])
set(gca,'ytick',[])
end
the output is:

Undefined function 'max' for input arguments of type 'cell'

I'm trying to plot bar chart for input data and to add data labels on each bar, when I run the program I got an error as "Undefined function 'max' for input arguments of type 'cell'." my code is...
data = [3 6 2 ;9 5 1];
figure; %// Create new figure
h = bar(data); %// Create bar plot
%// Get the data for all the bars that were plotted
x = get(h,'XData');
y = get(h,'YData');
ygap = 0.1; %// Specify vertical gap between the bar and label
ylim([0 12])
ylimits = get(gca,'YLim');
%// The following two lines have minor tweaks from the original answer
set(gca,'YLim',[ylimits(1),ylimits(2)+0.2*max(y)]);
labels = cellstr(num2str(data')) %//'
for i = 1:length(x) %// Loop over each bar
xpos = x(i); %// Set x position for the text label
ypos = y(i) + ygap; %// Set y position, including gap
htext = text(xpos,ypos,labels{i}); %// Add text label
set(htext,'VerticalAlignment','bottom', 'HorizontalAlignment','center')
end
when I give input as "data = [3 6 2 9 5 1]", the program runs fine
Matlab is a typeless language, so you don't know what type y is actually going to be. When you try data = [3 6 2 9 5 1] and call class(y) you will get double as an answer, which in this example is a vector of real numbers max() can work on.
However when you use data = [3 6 2 ; 9 5 1], you get different y :
>> class(y)
ans =
cell
>> y
y =
[1x2 double]
[1x2 double]
[1x2 double]
>>
Which means y is not a vector nor a matrix but a cell array that holds together three double vectors. max() does not know how to work on cell arrays and gives you
Undefined function 'max' for input arguments of type cell
error . You can find more on Matlab data types on http://www.mathworks.com/help/matlab/data-types_data-types.html
You can fix this error by turning y back into a vector, but as your labels will also change I will leave you here:
data = [3 6 2 ;9 5 1];
figure; %// Create new figure
h = bar(data); %// Create bar plot
%// Get the data for all the bars that were plotted
x = get(h,'XData');
y = get(h,'YData');
ygap = 0.1; %// Specify vertical gap between the bar and label
ylim([0 12])
ylimits = get(gca,'YLim');
y=[y{1} y{2} y{3}]; %works in this particular example
%// The following two lines have minor tweaks from the original answer
set(gca,'YLim',[ylimits(1),ylimits(2)+0.2*max(y)]);
labels = cellstr(num2str(data'))

generate rectangle annotation in the current figure

I would like to insert a rectangle into my matlab figure to highlight a specific region:
x = [0 1 2 2 3 4 5 6 7 8 9 10];
y = [0 1 2 4 3 4 5 6 7 8 9 10];
fh = figure(1);
plot(x,y)
xlim([0 10]);
ylim([0 10]);
I can do this by using the annotation function and defining the left bottom width height of the rectangle.
I am wondering, however, can this be done according to the x and y values from the figure in question? For the example shown, for example I would like to draw a rectangle from x = 1.5 y = 1.5 with a height of 3 and a width of two. This is my attempt:
% define location of lbwh in terms of x and y values
l = 1.5;
b = 1.5;
w = 2;
h = 3;
% convert factor of 1
xx = xlim;
l = l./xx(2);
b = b./xx(2);
w = w./xx(2);
h = h./xx(2);
annotation('rectangle','position',[l,b,w,h]);
The problem is that the position I'm providing is in terms of the (0,0) position in the plot and not the bottom left hand of the figure window. how can I correct this?
One way would be to just create a rectangle from line graphs:
plot([l,l,l+w,l+w,l],[b,b+h,b+h,b,b], 'r', 'LineWidth', 2)