Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

plotting order of 3D bar plots #732

Open
annacury opened this issue Aug 15, 2015 · 16 comments

Comments

@annacury
Copy link

commented Aug 15, 2015

I am trying to plot a 3d bar chart in Matlab . It works without problems. When I try to generate a tikz file it seems that the plotting order ist changed . the second bars are plotted on the first and the third on the second . I don't know which function do I need to avoid changing the plotting order . Any suggestions ? Thank you for your help

@egeerardyn

This comment has been minimized.

Copy link
Member

commented Aug 15, 2015

Do you have a small MATLAB script to recreate the behavior you are seeing?

Currently, there is no automatic way to change the plotting order. But with a small script, we can have a closer look at what is going on.

@egeerardyn egeerardyn added the +0.0.1 label Aug 15, 2015
@annacury

This comment has been minimized.

Copy link
Author

commented Aug 15, 2015

Yes I have the matlab script . With matlab there was no problems . The plotting order is correct but in tikz the order was changed . Can I include here a screenshot of the results I have ?

@egeerardyn

This comment has been minimized.

Copy link
Member

commented Aug 15, 2015

I can't reproduce this either using R2014b (both using the latest develop and master version (i.e. the one you get from FileExchange)):
screen shot 2015-08-15 at 17 22 55

Can you tell a bit more about:

  • which version of MATLAB/Octave you are using,
  • which version of matlab2tikz (latest stable one is 1.0.0),
  • which version of pgfplotsyou are using?

edit: You can include a screenshot by dragging & dropping the screenshot you took into the editing field (or by clicking on "selecting them").

@egeerardyn egeerardyn added the 3D plots label Aug 15, 2015
@thomas334

This comment has been minimized.

Copy link

commented Aug 15, 2015

Seem's like she asked the same question on stackechange (https://tex.stackexchange.com/questions/261413/pgfplots-3d-bar-chart-wrong-plotting-order). Maybe have a look at the last figure she added.

@annacury

This comment has been minimized.

Copy link
Author

commented Aug 15, 2015

yes the problem that I have just posted a small example but actually I am using more data and the plotting order is changed . I an using the latest matlab2tikz 1.0.0

@annacury

This comment has been minimized.

Copy link
Author

commented Aug 15, 2015

proof

@annacury

This comment has been minimized.

Copy link
Author

commented Aug 15, 2015

that was the result when I tried to plot all the data

@okomarov

This comment has been minimized.

Copy link
Member

commented Aug 15, 2015

Would it be possible to upload the whole code that generates that or the .fig file?

Basically, we are unable to cope with the NaNs in

table[row sep=crcr,header=false,meta index=3] {
NaN NaN NaN 1\\
0.6 0.6 0 1\\
...

There might be a workaround in how you build the 3d bar plot. Otherwise we need to investigate what generates that edge case.

@annacury

This comment has been minimized.

Copy link
Author

commented Aug 15, 2015

Yes one moment please . Thank you for your help

@egeerardyn

This comment has been minimized.

Copy link
Member

commented Aug 15, 2015

The NaNs are indeed a problem (not only don't we take proper care of them in matlab2tikz, but they behave oddly in pgpflots; e.g. normally you could add unbounded coords=discard to the options, but for some reason it really dislikes me when I try to do that for this figure).

I tried a few other options as well (e.g. mesh/ordering=y varies, all zbuffer options), but all to no avail. The only thing I can think of, is maybe if the bar plot is built layer-by-layer, that it might produce better results as the pgfplots manual indicates:

The z buffering algorithms of pgfplots apply only to a single \addplot command. Different \addplot commands will be drawn on top of each other, in the order of appearance.

So, I think that if you split your MATLAB commands, such that the figure is not plotted at once, but you start from the furthest layer (yellow in your figure), plot it and then plot the layers on top of it, you might get a lot better results. It's not very convenient, though, but from the pgfplots side, the 3D support is quite rudimentary (even more so for 3D bar plots).

@egeerardyn egeerardyn changed the title matlab2tikz plotting order plotting order of 3D bar plots Aug 15, 2015
@annacury

This comment has been minimized.

Copy link
Author

commented Aug 15, 2015

This is the matlab code I used to plot the 3d bar

lambda1 = [1e-3 1e-3 1e-3 1e-3 1e-3 1e-3 1e-3 1e-3 1e-3 1e-3 1e-3     5e-3 5e-3 5e-3 5e-3 5e-3 5e-3 5e-3 5e-3 5e-3 5e-3 5e-3    1e-2 1e-2 1e-2 1e-2 1e-2 1e-2 1e-2 1e-2 1e-2 1e-2  1e-2 5e-2 5e-2 5e-2 5e-2 5e-2 5e-2 5e-2 5e-2 5e-2 5e-2 5e-2    1e-1 1e-1 1e-1 1e-1 1e-1 1e-1 1e-1 1e-1 1e-1 1e-1  1e-1    5e-1 5e-1 5e-1 5e-1 5e-1 5e-1 5e-1 5e-1 5e-1 5e-1 5e-1     1  1  1  1  1  1  1  1  1  1  1  5 5 5 5 5 5 5 5 5 5 5   10 10 10 10 10 10 10 10 10 10 10 50 50 50 50 50 50 50 50 50 50 50   100 100 100 100 100 100 100 100 100 100 100 ] ;
L1=reshape(lambda1,[11,11]);
lambda2=[1e-1  5e-1 1   5   10  50  100 500 1000    5000    10000    1e-1  5e-1 1   5   10  50  100 500 1000    5000    10000   1e-1  5e-1  1   5   10  50  100 500 1000    5000    10000  1e-1  5e-1   1   5   10  50  100 500 1000    5000    10000  1e-1  5e-1   1   5   10  50  100 500 1000    5000    10000  1e-1  5e-1   1   5   10  50  100 500 1000    5000    10000  1e-1  5e-1   1   5   10  50  100 500 1000    5000    10000  1e-1  5e-1   1   5   10  50  100 500 1000    5000    10000  1e-1  5e-1   1   5   10  50  100 500 1000    5000    10000  1e-1  5e-1   1   5   10  50  100 500 1000    5000    10000  1e-1  5e-1   1   5   10  50  100 500 1000    5000    10000 ];            
L2=reshape(lambda2,[11,11]);
rmse_abundance = [1 2 3 4 5 6 7 8 9 10 11  12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11  12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11  12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11  12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11  12 13 14 15 16 17 18 19 20 21 22    23 24 25 26 27 28 29 90 91 92 93];       
figure ;
rmse_abu = reshape(rmse_abundance,[11,11]);
bar3(rmse_abu) ;
set(gca(gcf), 'xticklabel',{'1e-3', '5e-3' ,'1e-2', '5e-2', '1e-1', '5e-1' ,'1' ,'5' ,'10', '50' ,'100'},'yticklabel',{'1e-1', '5e-1', '1', '5' ,'10','50','100' ,'500' ,'1e3', '5e3' ,'1e4'});
xlabel('lambda1') ; ylabel ('lambda2'); zlabel('rmse abundance') ;
title('MVC');
@annacury

This comment has been minimized.

Copy link
Author

commented Aug 15, 2015

I have also tried with mesh/ordering=x varies but the results do not match with the matlab plots

@annacury

This comment has been minimized.

Copy link
Author

commented Aug 15, 2015

123
1234

@egeerardyn

This comment has been minimized.

Copy link
Member

commented Aug 15, 2015

I looked into bar3 a bit further, and it seems it does not have a syntax that supports building your plot more progressively. Behind the scenes, it should be possible to do what bar3 is doing with surface to do exactly that. However, that will take a bit of work (and while there is some demand for such a feature, I don't know whether somebody is willing to take on this job).

Unfortunately, I'm not sure whether there is a quick fix to your problem since the support of 3D bar graphs is rudimentary on all fronts (MATLAB, pgfplots and matlab2tikz).

@egeerardyn

This comment has been minimized.

Copy link
Member

commented Dec 22, 2015

With scatterbar3 being the latest Pick of the Week, I had a quick look at the underlying HG objects that it produces.

I guess that scatterbar3 may help to produce better figures also for matlab2tikz: it allows to place the bars at user-specified locations, so it should also be possible to build the graph layer-by-layer and hence overcome issues with the rudimentary pgfplots layering.

@Tacoma

This comment has been minimized.

Copy link

commented Nov 8, 2017

Hi, I know this issue is old, but as I had the same problem I wanted to share my solution:

I ended up using the code from scatterbar3 and reordering the bars and faces depending on the view direction set before creating the plot. The results are not exactly like the 'bar3' function and the x and y-axis might be switched.

mybar3.m

function mybar3(X,Y,Z)
%   mybar3(X,Y,Z) draws bars that look like BAR3 but can be exported by matlab2tikz
%
%   view(az, el) must be set _before_ calling this function
%
%   Z is the array of heights, X and Y two vectors with the positions, e.g. 
%   Z(1,3) is centered at X(1) and Y(3).
%
%   By changing the order of bar and face at creation time, the plot can be
%   exported with matlab2tikz as '.tex' file and used in LaTeX with correct
%   drawing order.

% By github.com/Tacoma - 2017-09-26

l = sum(sum(Z>0));
if l == 0
    warning('No bars with height Z > 0. Nothing to draw.');
    return;
end

px = zeros(l,1);
py = zeros(l,1);
pz = zeros(l,1);

k = 1;
[m,n] = size(Z);
% change ordering of individual bars depending on the view direction
[az, el] = view;
az = mod(az,360);
if az <90    
    steps_i = 1:1:m;
    steps_j = n:-1:1;
elseif az < 180
    steps_i = 1:1:m;
    steps_j = 1:1:n;
elseif az < 270
    steps_i = m:-1:1;
    steps_j = 1:1:n;
else
    steps_i = m:-1:1;
    steps_j = n:-1:1;
end

for i=steps_i
    for j=steps_j
        if Z(i,j) > 0
            px(k) = X(i);
            py(k) = Y(j);
            pz(k) = Z(i,j);
            
            k = k+1;
        end
    end
end

% Define bar_width to be smallest difference between two bars
lx = min(diff(unique([0; X])))*0.8;
ly = min(diff(unique([0; Y])))*0.8;
scatterbar3(px, py, pz, lx, ly);
dx = numel(X)+3;
dy = numel(Y);
pbaspect([dx dy (sqrt(5)-1)/2*dx])

function scatterbar3(X,Y,Z,LX,LY)
%SCATTERBAR3   3-D scatter bar graph.
%   SCATTERBAR3(X,Y,Z,LX,LY) draws 3-D bars of height Z at locations X and Y with lengths LX and LY.
%
%   X, Y and Z must be of equal size.  If they are vectors, than bars are placed
%   in the same fashion as the SCATTER3 or PLOT3 functions.
%
%   If they are matrices, then bars are placed in the same fashion as the SURF
%   and MESH functions. (not tested)
%
%   NOTE:  For best results, you should use the 'zbuffer' renderer.  To set the current
%   figure renderer to 'zbuffer' use the following command:
%
%       set(gcf,'renderer','zbuffer')

% By Mickey Stahl - 2002-02-25, edited by github.com/Tacoma 2017-09-26
% Engineering Development Group
% Aspiring Developer

[r,c]=size(Z);
for j=1:r
    for k=1:c
        if ~isnan(Z(j,k))
            drawbar(X(j,k),Y(j,k),Z(j,k),LX,LY)
        end
    end
end

zlim=[min(Z(:)) max(Z(:))];
if zlim(1)>0,zlim(1)=0;end
if zlim(2)<0,zlim(2)=0;end
axis([min(X(:))-LX/2 max(X(:))+LX/2 min(Y(:))-LY/2 max(Y(:))+LY/2 zlim*1.1])
axis 'auto z'
caxis([min(Y(:)) max(Y(:))])

function drawbar(x,y,z,lx,ly)

% Ordering of the faces of each bar. Only draw the faces that can be seen.
[az, el] = view;
az = mod(az,360);

if el > 0
    h(1)=patch(lx.*[-.5 -.5 .5 .5]+x,ly.*[-.5 .5 .5 -.5]+y,z.*[1 1 1 1],'b');   %top
else
    h(1)=patch(lx.*[-.5 -.5 .5 .5]+x,ly.*[-.5 .5 .5 -.5]+y,[0 0 0 0],'b');      % botton
end

if az > 90 & az < 270
    h(2)=patch(lx.*[-.5 -.5 .5 .5]+x,ly.*[.5 .5 .5 .5]+y,z.*[0 1 1 0],'b');     %back

else
    h(2)=patch(lx.*[-.5 -.5 .5 .5]+x,ly.*[-.5 -.5 -.5 -.5]+y,z.*[0 1 1 0],'b'); %front
end

if az < 180
    h(3)=patch(lx.*[.5 .5 .5 .5]+x,ly.*[-.5 -.5 .5 .5]+y,z.*[0 1 1 0],'b');     %right
else 
    h(3)=patch(lx.*[-.5 -.5 -.5 -.5]+x,ly.*[-.5 -.5 .5 .5]+y,z.*[0 1 1 0],'b'); %left
end


set(h,'facecolor','flat','FaceVertexCData',y)

---

It is really just a hack without many features of bar3, but it might be a good starting point for someone with the same problem. With the example above and

X = 1:11;
Y = 1:11;
view(62.5,30);
mybar3(X',Y',rmse_abu) ;

I get this result in LaTeX:

standalone

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.