Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ff64187

Browse files
Merge pull request #465 from plotly/fix_issue_445
fix issue #445
2 parents 460067b + e62e536 commit ff64187

File tree

1 file changed

+167
-108
lines changed

1 file changed

+167
-108
lines changed
Lines changed: 167 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,145 +1,196 @@
1-
function obj = updateHistogram2(obj,histIndex)
1+
function obj = updateHistogram2(obj,dataIndex)
22

3-
%---------------------------------------------------------------------%
3+
%--------------------------------------------------------------------------%
44

5-
%-AXIS INDEX-%
6-
axIndex = obj.getAxisIndex(obj.State.Plot(histIndex).AssociatedAxis);
5+
%-INITIALIZATIONS-%
76

8-
%---------------------------------------------------------------------%
7+
axIndex = obj.getAxisIndex(obj.State.Plot(dataIndex).AssociatedAxis);
8+
[xSource, ~] = findSourceAxis(obj, axIndex);
9+
plotData = get(obj.State.Plot(dataIndex).Handle);
10+
axisData = get(plotData.Parent);
911

10-
%-HIST DATA STRUCTURE- %
11-
hist_data = get(obj.State.Plot(histIndex).Handle);
12+
colorMap = axisData.Colormap;
13+
barGap = 0.05;
1214

13-
%---------------------------------------------------------------------%
15+
%-get trace data-%
16+
values = plotData.Values;
17+
xEdges = plotData.XBinEdges;
18+
yEdges = plotData.YBinEdges;
1419

15-
%-hist type-%
16-
obj.data{histIndex}.type = 'mesh3d';
20+
dx = diff(xEdges(2:end-1));
21+
dy = diff(yEdges(2:end-1));
1722

18-
%---------------------------------------------------------------------%
23+
if isinf(xEdges(1)) xEdges(1) = xEdges(2) - dx(1); end
24+
if isinf(yEdges(1)) yEdges(1) = yEdges(2) - dy(1); end
1925

20-
%-required parameters-%
21-
values = hist_data.Values;
22-
xedges = hist_data.XBinEdges;
23-
yedges = hist_data.YBinEdges;
26+
if isinf(xEdges(end)) xEdges(end) = xEdges(end-1) + dx(1); end
27+
if isinf(yEdges(end)) yEdges(end) = yEdges(end-1) + dy(1); end
2428

25-
sx = diff(xedges(2:end-1));
26-
sy = diff(yedges(2:end-1));
29+
[xData, yData, zData, iData, jData, kData] = ...
30+
getPlotlyMesh3d( xEdges, yEdges, values, barGap );
2731

28-
if isinf(xedges(1)) xedges(1) = xedges(2) - sx(1); end
29-
if isinf(yedges(1)) yedges(1) = yedges(2) - sy(1); end
32+
cData = zeros(size(zData));
33+
for n = 1:2:length(zData), cData(n:n+1) = max(zData(n:n+1)); end
3034

31-
if isinf(xedges(end)) xedges(end) = xedges(end-1) + sx(1); end
32-
if isinf(yedges(end)) yedges(end) = yedges(end-1) + sy(1); end
35+
%--------------------------------------------------------------------------%
3336

34-
%---------------------------------------------------------------------%
37+
%-set trace-%
38+
updateScene(obj, dataIndex);
3539

36-
%-get the values to use plotly's mesh3D-%
37-
bargap = 0.05;
38-
[X, Y, Z, I, J, K] = get_plotly_mesh3d(xedges, yedges, values, bargap);
40+
obj.data{dataIndex}.type = 'mesh3d';
41+
obj.data{dataIndex}.scene = sprintf('scene%d', xSource);
42+
obj.data{dataIndex}.name = plotData.DisplayName;
43+
obj.data{dataIndex}.visible = strcmp(plotData.Visible,'on');
44+
obj.layout.bargap = barGap;
3945

40-
%---------------------------------------------------------------------%
46+
%--------------------------------------------------------------------------%
4147

42-
%-passing parameters to mesh3D-%
43-
obj.data{histIndex}.x = X;
44-
obj.data{histIndex}.y = Y;
45-
obj.data{histIndex}.z = Z;
46-
obj.data{histIndex}.i = int16(I-1);
47-
obj.data{histIndex}.j = int16(J-1);
48-
obj.data{histIndex}.k = int16(K-1);
48+
%-set trace data-%
49+
obj.data{dataIndex}.x = xData;
50+
obj.data{dataIndex}.y = yData;
51+
obj.data{dataIndex}.z = zData;
52+
obj.data{dataIndex}.i = int16(iData - 1);
53+
obj.data{dataIndex}.j = int16(jData - 1);
54+
obj.data{dataIndex}.k = int16(kData - 1);
4955

50-
%---------------------------------------------------------------------%
56+
%--------------------------------------------------------------------------%
5157

52-
%-some settings-%
53-
% obj.data{histIndex}.color='rgb(0,255,0)';
54-
obj.data{histIndex}.contour.show = true;
55-
obj.data{histIndex}.contour.width = 6;
56-
obj.data{histIndex}.contour.color='rgb(0,0,0)';
57-
obj.data{histIndex}.flatshading = true;
58+
%-set trace coloring-%
59+
faceColor = plotData.FaceColor;
5860

59-
%---------------------------------------------------------------------%
61+
if isnumeric(faceColor)
62+
obj.data{dataIndex}.color = getStringColor(255*faceColor);
63+
elseif strcmp(faceColor, 'none')
64+
obj.data{dataIndex}.color = getStringColor(255*zeros(1,3), 0.1);
65+
elseif strcmp(faceColor, 'flat')
66+
obj.data{dataIndex}.intensity = cData;
67+
obj.data{dataIndex}.colorscale = getColorScale(colorMap);
68+
obj.data{dataIndex}.showscale = false;
69+
end
6070

61-
%-lighting settings-%
62-
obj.data{histIndex}.lighting.diffuse = 0.92;
63-
obj.data{histIndex}.lighting.ambient = 0.54;
64-
obj.data{histIndex}.lighting.specular = 1.42;
65-
obj.data{histIndex}.lighting.roughness = 0.52;
66-
obj.data{histIndex}.lighting.fresnel = 0.2;
67-
obj.data{histIndex}.lighting.vertexnormalsepsilon = 1e-12;
68-
obj.data{histIndex}.lighting.facenormalsepsilon = 1e-6;
71+
obj.data{dataIndex}.flatshading = true;
72+
obj.data{dataIndex}.lighting.diffuse = 0.92;
73+
obj.data{dataIndex}.lighting.ambient = 0.54;
74+
obj.data{dataIndex}.lighting.specular = 1.42;
75+
obj.data{dataIndex}.lighting.roughness = 0.52;
76+
obj.data{dataIndex}.lighting.fresnel = 0.2;
77+
obj.data{dataIndex}.lighting.vertexnormalsepsilon = 1e-12;
78+
obj.data{dataIndex}.lighting.facenormalsepsilon = 1e-6;
6979

70-
%---------------------------------------------------------------------%
80+
%--------------------------------------------------------------------------%
81+
end
7182

72-
%-aspect ratio-%
73-
ar = obj.PlotOptions.AspectRatio;
83+
function updateScene(obj, dataIndex)
7484

75-
if ~isempty(ar)
76-
if ischar(ar)
77-
obj.layout.scene.aspectmode = ar;
78-
elseif isvector(ar) && length(ar) == 3
79-
xar = ar(1);
80-
yar = ar(2);
81-
zar = ar(3);
82-
end
83-
else
85+
%-------------------------------------------------------------------------%
8486

85-
%-define as default-%
86-
xar = max(xedges(:));
87-
yar = max(yedges(:));
88-
zar = 0.7*max([xar, yar]);
89-
end
87+
%-INITIALIZATIONS-%
9088

91-
obj.layout.scene.aspectratio.x = xar;
92-
obj.layout.scene.aspectratio.y = yar;
93-
obj.layout.scene.aspectratio.z = zar;
89+
axIndex = obj.getAxisIndex(obj.State.Plot(dataIndex).AssociatedAxis);
90+
plotData = get(obj.State.Plot(dataIndex).Handle);
91+
axisData = get(plotData.Parent);
92+
[xSource, ~] = findSourceAxis(obj, axIndex);
93+
scene = eval( sprintf('obj.layout.scene%d', xSource) );
9494

95-
%---------------------------------------------------------------------%
95+
aspectRatio = axisData.PlotBoxAspectRatio;
96+
cameraPosition = axisData.CameraPosition;
97+
dataAspectRatio = axisData.DataAspectRatio;
98+
cameraUpVector = axisData.CameraUpVector;
99+
cameraEye = cameraPosition;
96100

97-
%-camera eye-%
98-
ey = obj.PlotOptions.CameraEye;
101+
rangeXLim = range(axisData.XLim);
102+
rangeYLim = range(axisData.YLim);
103+
rangeZLim = range(axisData.ZLim);
104+
cameraEye = cameraEye./[rangeXLim, rangeYLim rangeZLim];
105+
eyeNorm = max(abs(cameraEye)) - 1.4;
99106

100-
if ~isempty(ey)
101-
if isvector(ey) && length(ey) == 3
102-
obj.layout.scene.camera.eye.x = ey(1);
103-
obj.layout.scene.camera.eye.y = ey(2);
104-
obj.layout.scene.camera.eye.z = ey(3);
107+
if strcmp(plotData.DisplayStyle, 'tile')
108+
aspectRatio(3) = 1e-6;
109+
else
110+
eyeNorm2 = min([norm(aspectRatio([1,3])), norm(aspectRatio([2,3]))]);
111+
eyeNorm = eyeNorm - eyeNorm2 + 0.6;
105112
end
106-
else
107-
108-
%-define as default-%
109-
xey = - xar; if xey>0 xfac = -0.2; else xfac = 0.2; end
110-
yey = - yar; if yey>0 yfac = -0.2; else yfac = 0.2; end
111-
if zar>0 zfac = 0.2; else zfac = -0.2; end
112-
113-
obj.layout.scene.camera.eye.x = xey + xfac*xey;
114-
obj.layout.scene.camera.eye.y = yey + yfac*yey;
115-
obj.layout.scene.camera.eye.z = zar + zfac*zar;
116-
end
117113

118-
%---------------------------------------------------------------------%
114+
cameraEye = cameraEye / eyeNorm;
115+
116+
%-------------------------------------------------------------------------%
119117

118+
%-aspect ratio-%
119+
scene.aspectratio.x = aspectRatio(1);
120+
scene.aspectratio.y = aspectRatio(2);
121+
scene.aspectratio.z = aspectRatio(3);
120122

121-
%-zerolines hidded-%
122-
obj.layout.scene.xaxis.zeroline = false;
123-
obj.layout.scene.yaxis.zeroline = false;
124-
obj.layout.scene.zaxis.zeroline = false;
123+
%-camera eye-%
124+
scene.camera.eye.x = cameraEye(1);
125+
scene.camera.eye.y = cameraEye(2);
126+
scene.camera.eye.z = cameraEye(3);
125127

126-
%---------------------------------------------------------------------%
128+
%-camera up-%
129+
scene.camera.up.x = cameraUpVector(1);
130+
scene.camera.up.y = cameraUpVector(2);
131+
scene.camera.up.z = cameraUpVector(3);
127132

128-
%-layout bargap-%
129-
obj.layout.bargap = bargap;
133+
%-------------------------------------------------------------------------%
130134

131-
%-hist name-%
132-
obj.data{histIndex}.name = hist_data.DisplayName;
135+
%-get each scene axis-%
136+
scene.xaxis = getSceneAxis(axisData, 'X');
137+
scene.yaxis = getSceneAxis(axisData, 'Y');
138+
scene.zaxis = getSceneAxis(axisData, 'Z');
139+
140+
if strcmp(plotData.DisplayStyle, 'tile')
141+
scene.zaxis.visible = false;
142+
end
133143

134-
%-hist visible-%
135-
obj.data{histIndex}.visible = strcmp(hist_data.Visible,'on');
144+
%-------------------------------------------------------------------------%
136145

137-
%---------------------------------------------------------------------%
146+
%-SET SCENE TO LAYOUT-%
147+
obj.layout = setfield(obj.layout, sprintf('scene%d', xSource), scene);
138148

149+
%-------------------------------------------------------------------------%
139150
end
140151

152+
function ax = getSceneAxis(axisData, axName)
153+
154+
%-initializations-%
155+
axx = eval(sprintf('axisData.%sAxis', axName));
156+
ax.zeroline = false;
157+
ax.showline = true;
158+
ax.showspikes = true;
159+
ax.linecolor = getStringColor(255*axx.Color);
160+
ax.range = eval(sprintf('date2NumData(axisData.%sLim)', axName));
161+
162+
%-label-%
163+
label = eval(sprintf('axisData.%sLabel', axName));
164+
ax.title = label.String;
165+
if ~isempty(ax.title), ax.title = parseString(ax.title); end
166+
ax.titlefont.size = label.FontSize;
167+
ax.titlefont.color = getStringColor(255*label.Color);
168+
ax.titlefont.family = matlab2plotlyfont(label.FontName);
169+
170+
%-ticks-%
171+
ax.tickvals = axx.TickValues;
172+
ax.ticktext = axx.TickLabels;
173+
174+
ax.tickcolor = getStringColor(255*axx.Color);
175+
ax.tickfont.size = axx.FontSize;
176+
ax.tickfont.family = matlab2plotlyfont(axx.FontName);
177+
178+
switch axx.TickDirection
179+
case 'in'
180+
ax.ticks = 'inside';
181+
case 'out'
182+
ax.ticks = 'outside';
183+
end
184+
185+
%-grid-%
186+
axGrid = eval(sprintf('axisData.%sGrid', axName));
187+
if strcmp(axGrid, 'off'), ax.showgrid = false; end
188+
189+
%-box-%
190+
if strcmp(axisData.Box, 'on'), ax.mirror = true; end
191+
end
141192

142-
function bar_ = bar_data(position3d, size_)
193+
function bar_ = barData(position3d, size_)
143194
% position3d - 3-list or array of shape (3,) that represents the point of coords (x, y, 0), where a bar is placed
144195
% size = a 3-tuple whose elements are used to scale a unit cube to get a paralelipipedic bar
145196
% returns - an array of shape(8,3) representing the 8 vertices of a bar at position3d
@@ -167,7 +218,7 @@
167218
bar_ = bar_ + position3d; %translate each bar_ on the directio OP, with P=position3d
168219
end
169220

170-
function [vertices, I, J, K] = triangulate_bar_faces(positions, sizes)
221+
function [vertices, I, J, K] = triangulateBarFaces(positions, sizes)
171222
% positions - array of shape (N, 3) that contains all positions in the plane z=0, where a histogram bar is placed
172223
% sizes - array of shape (N,3); each row represents the sizes to scale a unit cube to get a bar
173224
% returns the array of unique vertices, and the lists i, j, k to be used in instantiating the go.Mesh3d class
@@ -183,12 +234,12 @@
183234
c = 1;
184235
for n = 1:size(positions, 1)
185236
if sizes(n, 3) ~= 0
186-
all_bars(:,:,c) = bar_data(positions(n,:), sizes(n,:))';
237+
all_bars(:,:,c) = barData(positions(n,:), sizes(n,:))';
187238
c = c+1;
188239
end
189240
end
190241

191-
% all_bars = [bar_data(pos, size) for pos, size in zip(positions, sizes) if size[2]!=0]
242+
% all_bars = [barData(pos, size) for pos, size in zip(positions, sizes) if size[2]!=0]
192243
[r, q, p] = size(all_bars);
193244

194245
% extract unique vertices from the list of all bar vertices
@@ -208,10 +259,9 @@
208259
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]);
209260
K = [ K; aux(:)];
210261
end
211-
212262
end
213263

214-
function [X, Y, Z, I, J, K] = get_plotly_mesh3d(xedges, yedges, values, bargap)
264+
function [X, Y, Z, I, J, K] = getPlotlyMesh3d(xedges, yedges, values, bargap)
215265
% x, y- array-like of shape (n,), defining the x, and y-ccordinates of data set for which we plot a 3d hist
216266

217267
xsize = xedges(2)-xedges(1)-bargap;
@@ -233,9 +283,18 @@
233283
sizes = [sizes; xsize, ysize, h(n)];
234284
end
235285

236-
[vertices, I, J, K] = triangulate_bar_faces(positions, sizes);
286+
[vertices, I, J, K] = triangulateBarFaces(positions, sizes);
237287
X = vertices(:,1);
238288
Y = vertices(:,2);
239289
Z = vertices(:,3);
290+
end
240291

292+
function colorScale = getColorScale(colorMap)
293+
nColors = size(colorMap, 1);
294+
normInd = rescale([1:nColors], 0, 1);
295+
colorScale = cell(nColors, 1);
296+
297+
for n = 1:nColors
298+
colorScale{n} = {normInd(n), getStringColor(255*colorMap(n, :))};
299+
end
241300
end

0 commit comments

Comments
 (0)