make bar plot with multiple y axis

前端 未结 1 1447
春和景丽
春和景丽 2021-01-20 21:44

I have some data I want to represent with a bar graph:

AAA=[2/3 1.5/3 .5/3 3; 1.5/3  1.8/3 .5/3 2.8];
figure
bar([1 2], AAA, \'BarWidth\', 1)
相关标签:
1条回答
  • 2021-01-20 22:05

    WARNING: This solution does not generalize easily when you have different numbers of bars... a different method that generalized a bit better is presented at the end

    From reading the docs, I don't see why plotyy wouldn't work (aside from being deprecated in favour of yyaxis in 2016a).

    plotyy(X1,Y1,X2,Y2,'function1','function2') uses function1(X1,Y1) to plot the data for the left axis and function2(X2,Y2) to plot the data for the right axis.

    y1 = [2/3 1.5/3 .5/3; 1.5/3  1.8/3 .5/3];
    y2 = [3; 2.8];
    x = [1,2];
    figure
    
    % based on http://stackoverflow.com/questions/18688381/matlab-bar-plot-grouped-but-in-different-y-scales
    offset = (x(2)-x(1))/16; %needs to be generalised, so the 16 should be something like 2^(size(y1,2)+1) or 2^(size(y1,2)+size(y2,2))
    width = (x(2)-x(1))/4; %The 4 here also needs to be generalized
    colors = {'b','g'};
    plotyy(x-offset*5,y1,x+offset*2,y2, @(x,y) bar(x,y,width*4,colors{1}), @(x,y) bar(x,y,width,colors{2}));
    

    But I would question whether or not it would be clearer to rather just use subplot


    If you want to change the colours of the individual bars (per category that is), you have to do it manually:

    h = plotyy(x-offset*5,y1,x+offset*2,y2, @(x,y) bar(x,y,width*4,colors{1}), @(x,y) bar(x,y,width,colors{2}));
    barGroup1 = h(1).Children;
    map1 = [0, 0, 0.4;
            0, 0, 0.6;
            0, 0, 1];
    for b = 1:numel(barGroup1)
        barGroup1(b).FaceColor = map1(b,:);
    end
    


    Another way to do this is instead of messing around with offset and width variables, just pad each y with a bunch of 0s:

    y1 = [2/3 1.5/3 .5/3,1; 1.5/3  1.8/3 .5/3,1;1,1,1,1];
    y2 = [3,1; 2.8,1;1,1];
    x = [1,2,4]; %x doesn't need to go up in increments of 1 (spacing will differ as you can see in the image), however it can only contain integers
    nCol = max(size(y1,2),size(y2,2))*2;
    Y1 = zeros(size(y1,1),nCol);
    Y2 = zeros(size(y2,1),nCol);
    % The idea is the make all the bars from group 1 sit before the group number (i.e. the numbers going from the halfway mark backwards) and all the bars from group 2 sit after the halfway mark (i.e. the numbers from the middle(+1) going forward)
    Y1(:,nCol/2-size(y1,2)+1:nCol/2) = y1
    Y2(:,nCol/2+1:nCol/2+1+size(y2,2)-1) = y2
    h = plotyy(x,Y1,x,Y2, @(x,y) bar(x,y,1,'b'), @(x,y) bar(x,y,1,'g'));
    

    You can colour this chart the same way as above. This should generalize no matter the number of bars. Unfortunately you can't control the size of the gap between the groups.

    0 讨论(0)
提交回复
热议问题