1+ function obj = updateHistogram2(obj ,histIndex )
2+
3+ % -AXIS INDEX-%
4+ axIndex = obj .getAxisIndex(obj .State .Plot(histIndex ).AssociatedAxis);
5+
6+ % -HIST DATA STRUCTURE- %
7+ hist_data = get(obj .State .Plot(histIndex ).Handle);
8+
9+ % -hist type-%
10+ obj.data{histIndex }.type = ' mesh3d' ;
11+
12+ % -required parameters-%
13+ values = hist_data .Values ;
14+ xedges = hist_data .XBinEdges ;
15+ yedges = hist_data .YBinEdges ;
16+
17+ % -get the values to use plotly's mesh3D-%
18+ bargap = 0.06 ;
19+ [X , Y , Z , I , J , K ] = get_plotly_mesh3d(xedges , yedges , values , bargap );
20+
21+ % -passing parameters to mesh3D-%
22+ obj.data{histIndex }.x = X ;
23+ obj.data{histIndex }.y = Y ;
24+ obj.data{histIndex }.z = Z ;
25+ obj.data{histIndex }.i = uint16(I - 1 );
26+ obj.data{histIndex }.j = uint16(J - 1 );
27+ obj.data{histIndex }.k = uint16(K - 1 );
28+
29+ % -some settings-%
30+ obj.data{histIndex }.color= [0.8 ,0.8 ,0.8 ];
31+ obj.data{histIndex }.contour.show = true ;
32+ obj.data{histIndex }.contour.color = ' black' ;
33+ obj.data{histIndex }.contour.width = 6 ;
34+ obj.data{histIndex }.flatshading = true ;
35+ obj.data{histIndex }.bordercolor = ' black' ;
36+ obj.data{histIndex }.borderwidth = 6 ;
37+
38+ % -layout bargap-%
39+ obj.layout.bargap = bargap ;
40+
41+ % -layout barmode-%
42+ obj.layout.barmode = ' group' ;
43+
44+ % -hist name-%
45+ obj.data{histIndex }.name = hist_data .DisplayName ;
46+
47+ % -hist visible-%
48+ obj.data{histIndex }.visible = strcmp(hist_data .Visible ,' on' );
49+
50+ end
51+
52+
53+ function bar_ = bar_data(position3d , size_ )
54+ % position3d - 3-list or array of shape (3,) that represents the point of coords (x, y, 0), where a bar is placed
55+ % size = a 3-tuple whose elements are used to scale a unit cube to get a paralelipipedic bar
56+ % returns - an array of shape(8,3) representing the 8 vertices of a bar at position3d
57+
58+ if nargin < 2
59+ size_ = [1 , 1 , 1 ];
60+ end
61+
62+ bar_ = [...
63+ 0 , 0 , 0 ; ...
64+ 1 , 0 , 0 ; ...
65+ 1 , 1 , 0 ; ...
66+ 0 , 1 , 0 ; ...
67+ 0 , 0 , 1 ; ...
68+ 1 , 0 , 1 ; ...
69+ 1 , 1 , 1 ; ...
70+ 0 , 1 , 1 ...
71+ ]; % the vertices of the unit cube
72+
73+ for n = 1 : size(bar_ , 1 )
74+ bar_(n ,: ) = bar_(n ,: ) .* size_ ; % scale the cube to get the vertices of a parallelipipedic bar_
75+ end
76+
77+
78+ bar_ = bar_ + position3d ; % translate each bar_ on the directio OP, with P=position3d
79+ end
80+
81+ function [vertices , I , J , K ] = triangulate_bar_faces(positions , sizes )
82+ % positions - array of shape (N, 3) that contains all positions in the plane z=0, where a histogram bar is placed
83+ % sizes - array of shape (N,3); each row represents the sizes to scale a unit cube to get a bar
84+ % returns the array of unique vertices, and the lists i, j, k to be used in instantiating the go.Mesh3d class
85+
86+ if nargin < 2
87+ sizes = ones(size(positions ,1 ), 3 ); % [(1,1,1)]*len(positions)
88+ else
89+ sizes ;
90+ % if isinstance(sizes, (list, np.ndarray)) and len(sizes) != len(positions):
91+ % raise ValueError('Your positions and sizes lists/arrays do not have the same length')
92+ end
93+
94+ c = 1 ;
95+ for n = 1 : size(positions , 1 )
96+ if sizes(n , 3 ) ~= 0
97+ all_bars(: ,: ,c ) = bar_data(positions(n ,: ), sizes(n ,: ))' ;
98+ c = c + 1 ;
99+ end
100+ end
101+
102+ % all_bars = [bar_data(pos, size) for pos, size in zip(positions, sizes) if size[2]!=0]
103+ [r , q , p ] = size(all_bars );
104+
105+ % extract unique vertices from the list of all bar vertices
106+ all_bars = reshape(all_bars , [r , p * q ])' ;
107+ [vertices , ~ , ixr ] = unique(all_bars , ' rows' );
108+
109+ % for each bar, derive the sublists of indices i, j, k assocated to its chosen triangulation
110+ I = [];
111+ J = [];
112+ K = [];
113+
114+ for k = 0 : p - 1
115+ aux = ixr([1 + 8 * k , 1 + 8 * k + 2 ,1 + 8 * k , 1 + 8 * k + 5 ,1 + 8 * k , 1 + 8 * k + 7 , 1 + 8 * k + 5 , 1 + 8 * k + 2 , 1 + 8 * k + 3 , 1 + 8 * k + 6 , 1 + 8 * k + 7 , 1 + 8 * k + 5 ]);
116+ I = [ I ; aux(: )];
117+ aux = ixr([1 + 8 * k + 1 , 1 + 8 * k + 3 , 1 + 8 * k + 4 , 1 + 8 * k + 1 , 1 + 8 * k + 3 , 1 + 8 * k + 4 , 1 + 8 * k + 1 , 1 + 8 * k + 6 , 1 + 8 * k + 7 , 1 + 8 * k + 2 , 1 + 8 * k + 4 , 1 + 8 * k + 6 ]);
118+ J = [ J ; aux(: )];
119+ aux = ixr([1 + 8 * k + 2 , 1 + 8 * k , 1 + 8 * k + 5 , 1 + 8 * k , 1 + 8 * k + 7 , 1 + 8 * k , 1 + 8 * k + 2 , 1 + 8 * k + 5 , 1 + 8 * k + 6 , 1 + 8 * k + 3 , 1 + 8 * k + 5 , 1 + 8 * k + 7 ]);
120+ K = [ K ; aux(: )];
121+ end
122+
123+ end
124+
125+ function [X , Y , Z , I , J , K ] = get_plotly_mesh3d(xedges , yedges , values , bargap )
126+ % x, y- array-like of shape (n,), defining the x, and y-ccordinates of data set for which we plot a 3d hist
127+
128+ xsize = xedges(2 )-xedges(1 )-bargap ;
129+ ysize = yedges(2 )-yedges(1 )-bargap ;
130+ [xe , ye ]= meshgrid(xedges(1 : end - 1 ), yedges(1 : end - 1 ));
131+ ze = zeros(size(xe ));
132+
133+ positions = zeros([size(xe ), 3 ]);
134+ positions(: ,: ,1 ) = ye ' ;
135+ positions(: ,: ,2 ) = xe ' ;
136+ positions(: ,: ,3 ) = ze ' ;
137+
138+ [m , n , p ] = size(positions );
139+ positions = reshape(positions , [m * n , p ]);
140+
141+ h = values ' ; h = h(: );
142+ sizes = [];
143+ for n = 1 : length(h )
144+ sizes = [sizes ; xsize , ysize , h(n )];
145+ end
146+
147+ [vertices , I , J , K ] = triangulate_bar_faces(positions , sizes );
148+ X = vertices(: ,1 );
149+ Y = vertices(: ,2 );
150+ Z = vertices(: ,3 );
151+
152+ end
0 commit comments