Matlab 使用堆叠条形图正确绘制图例

Matlab 使用堆叠条形图正确绘制图例,matlab,plot,Matlab,Plot,我想生成一个包含线条(plot,stairs)和条形(bar)的绘图。对于绘图和楼梯,我通常使用'DisplayName'属性来生成图例。对于堆叠的条形图绘图,这似乎不再有效。考虑这个MWE: x_max = 20; results = [3 37 50; 7 27 25; 11 0 13; 18 45 0]; figure('Position', [470 430 1000 600]); plot(0:x_max, polyval([3 1], 0:x_max), 'DisplayName',

我想生成一个包含线条(
plot
stairs
)和条形(
bar
)的绘图。对于
绘图
楼梯
,我通常使用
'DisplayName'
属性来生成图例。对于堆叠的
条形图
绘图,这似乎不再有效。考虑这个MWE:

x_max = 20;
results = [3 37 50; 7 27 25; 11 0 13; 18 45 0];
figure('Position', [470 430 1000 600]);
plot(0:x_max, polyval([3 1], 0:x_max), 'DisplayName', 'Production rate');
hold on; grid on;
bh = bar(results(:,1), results(:,2:3), 0.2, 'stacked', 'DisplayName', 'Fraction');
xlim([0 x_max]);
legend('Location', 'best');
set(gca, 'FontSize', 18);
hold off
它生成了这个图:

我想为两个分数中的每一个获得一个自定义图例条目,例如,
'Fraction1'、
。但是,这两个变量都会产生错误:

bar(results(:,1), results(:,2:3), 0.2, 'stacked', 'DisplayName', 'Fraction1', 'Fraction2')
bar(results(:,1), results(:,2:3), 0.2, 'stacked', 'DisplayName', {'Fraction1', 'Fraction2'})

>>Error setting property 'DisplayName' of class 'Bar':
Value must be a character vector or string scalar.
但如果我这样做了

bh.get('DisplayName')
我明白了

这意味着Matlab在内部确实为
'DisplayName'
生成了一个单元格数组,但不允许我指定一个。这失败了:

bh.set('DisplayName', {'Fraction1'; 'Fraction2'})

我知道我可以直接编辑图例条目的单元格数组,但我更喜欢
'DisplayName'
,因为当我更改绘图命令(或添加或删除任何命令)时,图例条目的顺序永远不会出错。任何解决方案?

作为一种快速解决方法,您可以在创建后设置每个条形图对象的
DisplayName
。 请参阅此基于您的示例的解决方案:

您遇到的问题是堆叠的
创建了一个
数组(在本例中为1x2)。您不能设置
Bar
数组的
DisplayName
属性,您需要设置数组中每个
Bar
的属性

% Your example code, without trying to set bar display names
x_max = 20;
results = [3 37 50; 7 27 25; 11 0 13; 18 45 0];
figure('Position', [470 430 1000 600]);
plot(0:x_max, polyval([3 1], 0:x_max), 'DisplayName', 'Production rate');
hold on; grid on;
bh = bar(results(:,1), results(:,2:3), 0.2, 'stacked');
xlim([0 x_max]);
legend('Location', 'best');
set(gca, 'FontSize', 18);
hold off

% Set bar names
names = {'Fraction1'; 'Fraction2'};
for n = 1:numel(names)
    set( bh(n), 'DisplayName', names{n} );
end
您可以在不使用循环的情况下执行此操作,但代价是语法稍微不那么明确:

names = {'Fraction1'; 'Fraction2'};
[bh(:).DisplayName] = names{:};

names = {'Fraction1'; 'Fraction2'};
[bh(:).DisplayName] = names{:};