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).
Thanks a lot!

Sign in to comment.

1 Answer

darova 님의 답변 14 Oct 2019
 채택된 답변

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 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.