No API supports functions `bar` and `legend` in multi-figure

1 次查看(过去 30 天)
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);
Warning: Ignoring extra legend entries.
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.

采纳的回答

Benjamin Kraus
Benjamin Kraus 2023-6-21
编辑:Benjamin Kraus 2023-6-21
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';
  1 个评论
Yihang Xu
Yihang Xu 2023-6-21
Thanks a lot. Option 1 works well.
i have thought about the option 2,but did not make this trade-off.

请先登录,再进行评论。

更多回答(1 个)

Vishnu
Vishnu 2023-6-21
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.
  1 个评论
Yihang Xu
Yihang Xu 2023-6-21
The results does not meet my expectations. However, i am inspired by it to write this code, just modify a number from 1 to 2
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);
Warning: Ignoring extra legend entries.
lgd.Layout.Tile = 'east';
lgd.String = {}; % clear existing legend strings
for i = 2:length(myLegends)
l(i) = line(nan, nan, 'LineWidth', 10, 'Color', colors(i,:));
lgd.String{i} = myLegends{i};
end

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Data Distribution Plots 的更多信息

产品


版本

R2023a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by