Reputation: 323
I am using Matlab 2019a and I want to bar-plot positive and negative vectors, positive ones above and negative ones below the x-axis. The following code works fine except for...
a) the colors and legends. I want to have the same colors and corresponding legend entries for each the revenue and the opex vector.
b) I want to have those vectors that are mostly negative (in this case opex) closer to the x-axis when they are positive than those that are mostly positive (in this case revenue). I.e. always revenue above opex in the positive part of the plot.
I'd like to write it in an efficient way so that I can generalize it for more vectors. Thank you!
clc
clear
close all
revenue = ones(100,1);
opex = -1*ones(100,1);
opex(10:15,1) = 3;
revenueNeg = revenue;
revenueNeg(revenueNeg>0) = 0;
revenuePos = revenue;
revenuePos(revenuePos<0) = 0;
opexNeg = opex;
opexNeg(opexNeg>0) = 0;
opexPos = opex;
opexPos(opexPos<0) = 0;
yDataNeg = [revenueNeg, opexNeg];
yDataPos = [revenuePos, opexPos];
hold on;
bar(yDataNeg,'stack')
bar(yDataPos,'stack')
legend('Revenue','Opex');
hold off;
Upvotes: 0
Views: 418
Reputation: 929
You can achieve (a) by storing a handle to the bar charts and setting the colors individually.
I'm interpreting (b) to mean that you want to sort the stack order according to the mean value of the series.
The code below can be expanded to more data series. You'll want to supply a label for each element of data
. Colors come from the parula
colormap. (You could pick something else like jet
if you prefer.)
[Edited in response to comments:]
data{1} = revenue;
data{2} = opex;
colors = parula(numel(data));
labels = {'Revenue','Opex'};
for i = 1:numel(data)
dataNeg{i} = data{i};
dataNeg{i}(data{i}>0) = 0;
dataPos{i} = data{i};
dataPos{i}(data{i}<0) = 0;
mdata(i) = nnz(dataPos{i}); % was: mean(data{i});
end;
[~,posOrder] = sort(mdata,'ascend');
[~,negOrder] = sort(mdata,'descend');
yDataPos = [dataPos{posOrder}];
yDataNeg = [dataNeg{negOrder}];
hold on;
bNeg = bar(yDataNeg,'stack');
bPos = bar(yDataPos,'stack');
for i= 1:numel(data)
set(bNeg(i),'FaceColor',colors(negOrder(i),:))
set(bPos(i),'FaceColor',colors(posOrder(i),:))
end;
legend(labels{:});
hold off;
Upvotes: 1