简体   繁体   中英

reverse ordering of legend colors in matlab bar plot

Trying to change some of the properties associated with the bar plot in matlab is very confusing. I have found a number of solution to my problems here. However, there is one that I cannot find. Consider the following:

ax1 = subplot(121);
id2 = [8;2;3;5];
id2_t = sum(id2);
id3 = (id2/id2_t).*100; id3(:,2) = 0;
H1 = bar(id3','stacked','EdgeColor','none');
set(gca,'XTicklabel',[]);
xlim([0.75 1.25]);

% add legend
str = {'str1','str2','str3','str4'};
ll = legend(str);
legend('boxoff');
set(ll,'PlotBoxAspectRatio',[0.5 1 1]);
ll_i = get(ll,'position');
set(ll, 'Position', [0.25 ll_i(2)-0.1 ll_i(3) ll_i(4)]);

% change dimensions of plot
AX1 = get(ax1,'position');
set(ax1,'position',[AX1(1) AX1(2) AX1(3)/2.7 AX1(4)]);

This code was written to produce a single stacked bar in matlab, not the most sophisticated of solutions, but it works. The bar plot I get is below:

在此处输入图片说明

Now I am trying to reverse the order of my legend entries so that they match up with the plot. Some people have suggested flipud or fliplr on the strings, but this doesnt work. This changes the sequence of the strings but does not change the colors. Can anyone suggest a method that an match up the ordering of the colors between the legend and the plot? For example, str4 should be blue

Note that the flipud suggestion works for line plots, but not for a stacked bar plot like this. Example using line plot:

x = 1:10;
h = zeros(5, 1);
hold on;
cols = {'r', 'g', 'b', 'y', 'k'};
for k = 1:5
    h(k) = plot(x, k*x, cols{k});
end
legend({'one','two','three', 'four', 'five'}) % one way
legend(flipud(h), {'one', 'two', 'three', 'four', 'five'}) % another way

Solution

Here is the solution using the answer provided by Dan:

ax1 = subplot(121);
id2 = [8;2;3;5];
id2_t = sum(id2);
id3 = (id2/id2_t).*100; id3(:,2) = 0;
H1 = bar(id3','stacked','EdgeColor','none');
set(gca,'XTicklabel',[]);
xlim([0.75 1.25]);

% add legend
str = {'str1','str2','str3','str4'};
[ll ll2]= legend(str);
legend('boxoff');
set(ll,'PlotBoxAspectRatio',[0.5 1 1]);
ll_i = get(ll,'position');
set(ll, 'Position', [0.25 ll_i(2)-0.1 ll_i(3) ll_i(4)]);

% change dimensions of plot
AX1 = get(ax1,'position');
set(ax1,'position',[AX1(1) AX1(2) AX1(3)/2.7 AX1(4)]);

map = colormap;
n = size(ll2,1);
MAP = map(linspace(size(map,1),1,n/2),:); %// n is as my code above
for k = (n/2 + 1):n;
    a1 = get(ll2(k),'Children');
    set(a1,'FaceColor',MAP(k-n/2,:));
end

在此处输入图片说明

So you can control the colours of the legend independently of the colors of the bar chart like this (note that I got this idea based on this post and then by inspecting the object properties in the command line):

[ll, ll2] = legend(str);

n = size(ll2,1);
for k = (n/2 + 1):n
    ll2(k).Children.FaceColor = RGBTriple;
end

So try setting RGBTriple to [1,0,0] and you should see all the legend boxes become red. So now it's just a case of getting the bar chart colors (probably in a very similar manner) and flipping them.

OK so here is a hacky way to find the right colors:

  1. Get the current colormap:

     map = colormap; 
  2. Reduce the colormap to the size of your legend:

     MAP = map(linspace(size(map,1),1,n/2),:); %// n is as my code above 
  3. Use it for RGBTriple:

     for k = (n/2 + 1):n ll2(k).Children.FaceColor = MAP(kn/2,:); end 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM