0

I am plotting some data with bar3 in Matlab.

In the plot, I would like to make the zero value blank, but I want to keep the black edge of each zero cell (i.e. the black line around the cell).

So far I could only find an answer which totally removes the data in a null cell: both the bar and its edge... cf How to hide zero values in bar3 plot in MATLAB.

Has anybody an idea to do that?

Thank you in advance.

Community
  • 1
  • 1
user3911415
  • 15
  • 1
  • 5
  • With `bar3`, it is not possible to modify the face color of random bars, because `bar3` plots data column by column, so it is only possible to change the face color of entire columns. – Bentoy13 Aug 06 '14 at 07:23

1 Answers1

1

Following my comment, here is a solution. To sum up simply, you cannot change the color of only one bar drawn by bar3.

Instead of displaying each bar by hand, my solution is to modify the code of bar3 in order to draw each bar independently, which you can read freely. This is rather simple when you analyse the code of bar3: each bar is the graphic representation of 6*4 data matrices. The block of code in question is the following:

for i=1:size(yy,2)/4
    h = [h,surface('xdata',xx+x(i),...
            'ydata',yy(:,(i-1)*4+(1:4)), ...
            'zdata',zz(:,(i-1)*4+(1:4)),...
            'cdata',i*cc, ...
            'FaceColor',facec,...
            'EdgeColor',edgec,...
            'tag','bar3',...
            'parent',cax)];
end

As you see, surface is called on every data column. To call surface on each element, you can modify the code as follows:

for i=1:size(yy,2)/4
    for j=1:size(yy,1)/6
        h = [h,surface('xdata',xx((j-1)*6+(1:5),:)+x(i),...
                'ydata',yy((j-1)*6+(1:5),(i-1)*4+(1:4)), ...
                'zdata',zz((j-1)*6+(1:5),(i-1)*4+(1:4)),...
                'cdata',i*cc((j-1)*6+(1:5),:), ...
                'FaceColor',facec,...
                'EdgeColor',edgec,...
                'tag','bar3',...
                'parent',cax)];
    end
end

You cannot modify the original bar3, so let's save it as bar3_mod.

With this done, if you refer to the doc article about Color 3-D Bars by Height, it is now really simple to make bars of zero height transparent. Before this, remember that the height of a bar you get with a get on the handle of one bar is described by a 5*4 matrix of the form:

NaN     0     0   NaN
  0     Z     Z     0
  0     Z     Z     0
NaN     0     0   NaN
NaN     0     0   NaN

So you must only test the value of the element at (2,2) and change the color as you want. In your case, it's quite simple to derive the code given in the linked page:

h = bar3_mod(Z);
for k = 1:length(h)
    zdata = get(h(k),'ZData');
    if zdata(2,2)==0
        set(h(k),'CData',zdata,'FaceColor','none');
    end
end

I've tested it on an example, with magic(5) as input and making the bar with a height of 1 transparent:

bar3_mod + transparent bar

EDIT

Like bar3, there is one color per data column. If you want to color each bar according to it's value, you can either modify the code of bar3_mod or add a few more instructions when you make the specified bars transparent.

1st solution: quite simple to change the for-loop:

for i=1:size(yy,2)/4
    for j=1:size(yy,1)/6
        h = [h,surface('xdata',xx((j-1)*6+(1:5),:)+x(i),...
                'ydata',yy((j-1)*6+(1:5),(i-1)*4+(1:4)), ...
                'zdata',zz((j-1)*6+(1:5),(i-1)*4+(1:4)),...
                'cdata',zz((j-1)*6+2,(i-1)*4+2)*cc((j-1)*6+(1:5),:), ... % here is the modification
                'FaceColor',facec,...
                'EdgeColor',edgec,...
                'tag','bar3',...
                'parent',cax)];
    end
end

2nd solution: just add a else case where you affect the new color data:

for k = 1:length(h)
    zdata = get(h(k),'ZData');
    if zdata(2,2)==0
        set(h(k),'CData',zdata,'FaceColor','none');
    else
        set(h(k),'CData',ones(size(zdata))*zdata(2,2));
    end
end
Bentoy13
  • 4,886
  • 1
  • 20
  • 33
  • Thank you very much, it works like a charm! I did not know enough about the functioning of bar3 function, so I could not have found it myself. – user3911415 Aug 07 '14 at 06:53
  • @user3911415 Matlab is quite open with the high level functions: these are simple scripts. So you can view it easily, just open it with Ctrl+D and you'll see how it really works. That's exactly the way I solve your problem! – Bentoy13 Aug 07 '14 at 07:13
  • Another question, which should be straightforward for you (but not for me) is: With this new bar3_mod function, I also want to color each bar according to its height (except the zeros, of course). I usually use that code: `code` for l=1:length(h) zdata=ones(6*length(h),4); k=1; for j=0:6:(6*length(h)-6) zdata(j+1:j+6,:)=input(k,l); k=k+1; end set(h(l),'Cdata',zdata) end `code` I did find quickly how to modify it (quite fluent in matlab, but I never play with high level functions). – user3911415 Aug 07 '14 at 07:26
  • It works. I tried something similar to your 2nd solution but without multiplying by the matrix ones(size(zdata)) in the argument of the function set. Thanks! – user3911415 Aug 07 '14 at 07:59