No API supports functions `bar` and `legend` in multi-figure
2 views (last 30 days)
Show older comments
clear, close all
x1 = rand(1,18);
x2 = rand(1,18);
x3 = rand(1,18);
x4 = rand(1,18);
myLegends = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R"};
colors = rand(18,3);
t = tiledlayout('flow', 'TileSpacing', 'compact');
nexttile
b1 = bar(x1);
b1.FaceColor = 'flat';
for i = 1:length(colors)
b1.CData(i,:) = colors(i,:);
end
set(gca,'XTickLabel',[]);
nexttile
b2 = bar(x2);
b2.FaceColor = 'flat';
for i = 1:length(colors)
b2.CData(i,:) = colors(i,:);
end
set(gca,'XTickLabel',[]);
nexttile
b3 = bar(x3);
b3.FaceColor = 'flat';
for i = 1:length(colors)
b3.CData(i,:) = colors(i,:);
end
set(gca,'XTickLabel',[]);
nexttile
b4 = bar(x4);
b4.FaceColor = 'flat';
for i = 1:length(colors)
b4.CData(i,:) = colors(i,:);
end
set(gca,'XTickLabel',[]);
lgd = legend(myLegends);
lgd.Layout.Tile = 'east';
i'd like to create a legend on the right, and the legend should contains 18 labels corresponding to the colors. i tried my best but failed.
The main reason is that the bar function does not support individual bars forming a group, resulting in the legend function not being able to recognize bars of different colors.
The second reason lies in that `legend` function does not support custom creation, that is, creating with preset colors and labels from the scratch.
Call on developers to make improvements.
0 Comments
Accepted Answer
Benjamin Kraus
on 21 Jun 2023
Edited: Benjamin Kraus
on 21 Jun 2023
You can only have one legend entry per bar object, and each of your calls to the bar command creates only one bar object.
You have two options:
Option 1: Multiple calls to bar
@Vishnu is on the right track with the first option (which is to call the bar command multiple times), but left out the x-data when calling the bar command:
x1 = rand(1,18);
x2 = rand(1,18);
x3 = rand(1,18);
x4 = rand(1,18);
myLegends = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R"};
colors = rand(18,3);
t = tiledlayout('flow', 'TileSpacing', 'compact');
nexttile
b1 = bar(1, x1(1),'FaceColor',colors(1,:));
hold on
for i = 2:height(colors)
b1(i) = bar(i, x1(i), 'FaceColor',colors(i,:));
end
xticks auto
nexttile
b2 = bar(1, x2(1),'FaceColor',colors(1,:));
hold on
for i = 2:height(colors)
b2(i) = bar(i, x2(i), 'FaceColor',colors(i,:));
end
xticks auto
nexttile
b3 = bar(1, x3(1),'FaceColor',colors(1,:));
hold on
for i = 2:height(colors)
b3(i) = bar(i, x3(i), 'FaceColor',colors(i,:));
end
xticks auto
nexttile
b4 = bar(1, x4(1),'FaceColor',colors(1,:));
hold on
for i = 2:height(colors)
b4(i) = bar(i, x4(i), 'FaceColor',colors(i,:));
end
xticks auto
lgd = legend(b4, myLegends);
lgd.Layout.Tile = 'east';
Option 2: Use a diagonal matrix
This version produces the same results as the above, but it cheats a little and uses a diagonal matrix to do it.
figure
t = tiledlayout('flow', 'TileSpacing', 'compact');
nexttile
x1Mat = diag(x1);
b1 = bar(x1Mat,'stacked');
for i = 1:numel(b1)
b1(i).FaceColor = colors(i,:);
end
set(gca,'XTickLabel',[]);
nexttile
x2Mat = diag(x2);
b2 = bar(x2Mat,'stacked');
for i = 1:numel(b2)
b2(i).FaceColor = colors(i,:);
end
set(gca,'XTickLabel',[]);
nexttile
x3Mat = diag(x3);
b3 = bar(x1Mat,'stacked');
for i = 1:numel(b3)
b3(i).FaceColor = colors(i,:);
end
set(gca,'XTickLabel',[]);
nexttile
x4Mat = diag(x4);
b4 = bar(x4Mat,'stacked');
for i = 1:numel(b4)
b4(i).FaceColor = colors(i,:);
end
set(gca,'XTickLabel',[]);
lgd = legend(b4, myLegends);
lgd.Layout.Tile = 'east';
More Answers (1)
Vishnu
on 21 Jun 2023
Hi Yihang,
It looks like you are trying to create a bar plot with individual colors for each bar and add a legend to it. Unfortunately, the legend function won't be able to recognize bars with different colors when they are created separately using the bar function.
However, you can create the legend manually using a loop to plot each color with its corresponding label. Here is the code ,
clear, close all
x1 = rand(1,18);
x2 = rand(1,18);
x3 = rand(1,18);
x4 = rand(1,18);
myLegends = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R"};
colors = rand(18,3);
t = tiledlayout('flow', 'TileSpacing', 'compact');
nexttile
b1 = bar(x1,'FaceColor',colors(1,:));
set(gca,'XTickLabel',[]);
hold on;
for i = 2:length(colors)
tempbar = bar(x1(i),'FaceColor',colors(i,:));
end
nexttile
b2 = bar(x2,'FaceColor',colors(1,:));
set(gca,'XTickLabel',[]);
hold on;
for i = 2:length(colors)
tempbar = bar(x2(i),'FaceColor',colors(i,:));
end
nexttile
b3 = bar(x3,'FaceColor',colors(1,:));
set(gca,'XTickLabel',[]);
hold on;
for i = 2:length(colors)
tempbar = bar(x3(i),'FaceColor',colors(i,:));
end
nexttile
b4 = bar(x4,'FaceColor',colors(1,:));
set(gca,'XTickLabel',[]);
hold on;
for i = 2:length(colors)
tempbar = bar(x4(i),'FaceColor',colors(i,:));
end
lgd = legend(myLegends,'Location','east');
lgd.String = {}; % clear existing legend strings
for i = 1:length(myLegends)
l(i) = line(nan, nan, 'LineWidth', 10, 'Color', colors(i,:));
lgd.String{i} = myLegends{i};
end
% you can move the lengend by dragging it, after running in MATLAB.
See Also
Categories
Find more on Legend in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!