MATLAB Answers

0

bar chart with wrong legend referring

Asked by Elena Casiraghi on 14 Oct 2019
Latest activity Commented on by Elena Casiraghi on 15 Oct 2019
Dear, I have a problem with bar charts:
I hve this data:
datasets = {'Dataset1', 'Dataset2','Dataset3' };
methods = {'A', 'B', 'C', 'D', 'E'};
% rows refer to datasets, columns to methods
data = [0.9150 0.7600 0.6400 0.5800 0.4800;
0.7840 0.6100 0.6700 0.6600 0.6400;
0.7440 0.5900 0.6300 0.6200 0.7000];
% errors (rows refer to datasets, columns to methods)
error =[0.0190 0.0230 0.0170 0.0430 0.0350;
0.0210 0.0180 0.0250 0.0400 0.0330;
0.0180 0.0200 0.0190 0.0420 0.0290];
% defining my own colors
baseMap = double([[255,255,50];
[138,177,211];
[179,222,115];
[222,213,250];
[255,128,124];]);
map = round(baseMap./255,2);
data contains performance for 5 different methods, over three datasets.
I want to plot a grouped barchart, similar to the one in the attached image, where each bar is characterized by a color.
Each group of bars refers to experiments over one dataset. And the position of the bars is so that they are sorted in order in descending order of performance.
I somehow successfully oredered the bars and showed them with differing colors with this code:
datasets = {'Dataset1', 'Dataset2','Dataset3' };
methods = {'A', 'B', 'C', 'D', 'E'};
data = [0.9150 0.7600 0.6400 0.5800 0.4800;
0.7840 0.6100 0.6700 0.6600 0.6400;
0.7440 0.5900 0.6300 0.6200 0.7000];
error =[0.0190 0.0230 0.0170 0.0430 0.0350;
0.0210 0.0180 0.0250 0.0400 0.0330;
0.0180 0.0200 0.0190 0.0420 0.0290];
baseMap = double([[255,255,50];
[138,177,211];
[179,222,115];
[222,213,250];
[255,128,124];]);
map = round(baseMap./255,2);
% finding sorted positions
indsort = NaN(size(data)); dataS = indsort;
indsort(1,:) = 1:size(data,2);
for nD = 1: size(data,1)
[~, indsort(nD,:)] = sort(data(nD,:),'descend');
end
fig = figure;
colormap(map);
% Creating axes and the bar graph
ax = axes;
% Properties of the bar graph as required
ax.YGrid = 'on';
ax.GridLineStyle = '-';
xticks(ax,[1 2 3]);
% Naming each of the bar groups
xticklabels(ax,datasets);
% X and Y labels
xlabel ('Dataset');
ylabel ('AUROC');
%title('Mean and standard deviation AUROC values obtained on Breast, Colorectal, Colon datasets.')
% Creating a legend and placing it outside the bar plot
hold on;
% Finding the number of groups and the number of bars in each group
ngroups = size(data, 1);
nbars = size(data, 2);
% Calculating the width for each bar group
groupwidth = min(1, 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 nB = 1:nbars
for nD = 1:ngroups
i = find(indsort(nD,:) == nB);
% Calculate center of the bar
x = nD - groupwidth/2 + (2*i-1) * groupwidth / (2*nbars);
bar(x, data(nD,nB), 'FaceColor', map(nB,:),'EdgeColor',map(nB,:),'BarWidth',0.12);
errorbar(x, data(nD,nB), error(nD,nB), 'k', 'linestyle', 'none');
end
end
lg = legend(methods);
lg.Location = 'BestOutside';
lg.Orientation = 'Horizontal';
however, if you watch the generated picture, there are two problems The legend is wrong
How can I set these problem?

  6 Comments

:)))
thanks again!
Hope this example will be useful to someone!
About the width of each group and the dinstance between groups in grouped bar chart, is it explained somewhere? I copied it from another question.
Again, my pleasure!
See the documentation for the bar function, and its properties (linked to at the end of the documentation page).

Sign in to comment.

1 Answer

Answer by darova
on 14 Oct 2019
 Accepted Answer

Get handlers (put it into for loop)
h(nB) = bar(x, data(:,nB), 'FaceColor', map(nB,:),'BarWidth',0.1);
And try this
w = 0.05; % new width
for i = 1:length(h)
h1 = get(h(i),'Children');
X = get(h1,'Xdata');
Y = get(h1,'Ydata');
mX = mean(X); % find middle of a bar
X1 = [mX-w; mX-w; mX+w; mX+w];
set(h1,'Xdata',X1) % this operation somehow changes Y data
set(h1,'Ydata',Y); % set old/original Y data
end
lg = legend(h,methods); % assign legend to handlers of bar

  3 Comments

Dear, thanks for your suggestion. however, it causes a matlab error; I integrated it like that
load('dataMatlab.mat');
baseMap = double([[255,255,50];
[138,177,211];
[179,222,115];
[222,213,250];
[255,128,124];]);
map = round(baseMap./255,2);
% finding sorted positions
indsort = NaN(size(data)); dataS = indsort;
indsort(1,:) = 1:size(data,2);
for nD = 1: size(data,1)
[~, indsort(nD,:)] = sort(data(nD,:),'descend');
end
fig = figure;
colormap(map);
% Creating axes and the bar graph
ax = axes;
% Properties of the bar graph as required
ax.YGrid = 'on';
ax.GridLineStyle = '-';
xticks(ax,[1 2 3]);
% Naming each of the bar groups
xticklabels(ax,datasets);
% X and Y labels
xlabel ('Dataset');
ylabel ('AUROC');
%title('Mean and standard deviation AUROC values obtained on Breast, Colorectal, Colon datasets.')
% Creating a legend and placing it outside the bar plot
hold on;
% Finding the number of groups and the number of bars in each group
ngroups = size(data, 1);
nbars = size(data, 2);
% Calculating the width for each bar group
groupwidth = min(1, 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
h = []; count =1;
for nB = 1:nbars
for nD = 1:ngroups
i = find(indsort(nD,:) == nB);
% Calculate center of the bar
x = nD - groupwidth/2 + (2*i-1) * groupwidth / (2*nbars);
h(count) = bar(x, data(nD,nB), 'FaceColor', map(nB,:),'EdgeColor',map(nB,:),'BarWidth',0.12);
count = count+1;
errorbar(x, data(nD,nB), error(nD,nB), 'k', 'linestyle', 'none');
end
end
w = 0.05; % new width
for i = 1:length(h)
h1 = get(h(i),'Children');
X = get(h1,'Xdata');
Y = get(h1,'Ydata');
mX = mean(X); % find middle of a bar
X1 = [mX-w; mX-w; mX+w; mX+w];
set(h1,'Xdata',X1) % this operation somehow changes Y data
set(h1,'Ydata',Y); % set old/original Y data
end
lg = legend(h,methods); % assign legend to handlers of bar
ERROR:Error using matlab.ui.Figure/get
There is no Xdata property on the Figure class.
Error in dataPlotQUASIImproved (line 59)
X = get(h1,'Xdata');
darova
on 14 Oct 2019
I have older version of MATLAB. Try:
for i = 1:length(h)
% h1 = get(h(i),'Children');
X = get(h(i),'Xdata');
Y = get(h(i),'Ydata');
mX = mean(X); % find middle of a bar
X1 = [mX-w; mX-w; mX+w; mX+w];
set(h(i),'Xdata',X1) % this operation somehow changes Y data
set(h(i),'Ydata',Y); % set old/original Y data
end
I get this image...
and the legend is still wrong...
Thanks anyway; I think there is no solution.

Sign in to comment.