MATLAB Answers

Bars disappear with log scale

1 view (last 30 days)
Executing the following four commands
Y = count(1:10,:);
figure
bar3h(Y,'grouped')
set(gca,'YScale','log')
gives me the plot without the bars? how could I restore the body of each bar?
Thanks for any help
  1 Comment
Adam Danz
Adam Danz on 1 Jun 2021
@wael Ghareeb Welcome to the forum. I've edited your question to format your code. In the future please use the code/text toggle in rich text editor to format your code.

Sign in to comment.

Accepted Answer

Adam Danz
Adam Danz on 1 Jun 2021
Reproducing the problem
Well, that's interesting. The plot on the left shows the bar plot with a linear y-axis and the plot on the right is the same bar plot but with a log y-axis.
load count.dat % built-in
Y = count(1:10,:);
figure
subplot(1,2,1)
bar3h(Y,'grouped')
xlabel('x axis')
ylabel('y axis')
zlabel('z axis')
title('Linear y scale')
subplot(1,2,2)
bar3h(Y,'grouped')
set(gca,'YScale','log')
xlabel('x axis')
ylabel('y axis')
zlabel('z axis')
title('Log y scale')
Cause of the problem
The 3D bar plots are constructed by surfaces stored in the output to bar3h. The horizontal walls extend from y=0 to the height of the each bar. When converting the y-axis to a log scale, log(0) returns -inf which cannot be plotted so the sections of the surfaces that include vertices at y=0 vanish. This does not affect the tops of each bar unless the tops are at y=0.
Solution
After constructing the bar plot, change values equal to or less than y=0. In the example below, they are changed to 1; log(1)=0.
load count.dat % built-in
Y = count(1:10,:);
figure
subplot(1,2,1)
bar3h(Y,'grouped')
xlabel('x axis')
ylabel('y axis')
zlabel('z axis')
title('Linear y scale')
subplot(1,2,2)
bh = bar3h(Y,'grouped');
for i = 1:numel(bh)
zeroIdx = bh(i).YData == 0;
bh(i).YData(zeroIdx) = 1;
end
set(gca,'YScale','log')
xlabel('x axis')
ylabel('y axis')
zlabel('z axis')
title(['Log y scale with',newline,'y=0 adjustment'])
  1 Comment
wael Ghareeb
wael Ghareeb on 1 Jun 2021
Thank you for your help and explanation.

Sign in to comment.

More Answers (1)

Joseph Cheng
Joseph Cheng on 1 Jun 2021
While not ideal this should get you by since bar tries to plot the bar all the way to 0 which log scales don't show
y=randi(100,10,10);
figure(1),clf
hbar = bar3h(y,'grouped')
hbar =
1×10 Surface array: Surface Surface Surface Surface Surface Surface Surface Surface Surface Surface
set(gca,'Yscale','log')
minY2plt = 0.001;
for ind = 1:10
hbar(ind).YData(hbar(ind).YData==0)=minY2plt;
end
ylim([minY2plt max(y(:))])
  1 Comment
wael Ghareeb
wael Ghareeb on 1 Jun 2021
Thank you for you help. It works.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!