diff --git a/plotly/plotlyfig_aux/core/updateData.m b/plotly/plotlyfig_aux/core/updateData.m
index e790c4cc..45c24b0a 100644
--- a/plotly/plotlyfig_aux/core/updateData.m
+++ b/plotly/plotlyfig_aux/core/updateData.m
@@ -34,7 +34,9 @@
elseif strcmpi(obj.PlotOptions.TreatAs, 'mesh')
updateMesh(obj, dataIndex);
elseif strcmpi(obj.PlotOptions.TreatAs, 'surfc')
- updateSurfc(obj, dataIndex);
+ updateSurfc(obj, dataIndex);
+ elseif strcmpi(obj.PlotOptions.TreatAs, 'bubblecloud')
+ updateBubblecloud(obj,dataIndex);
% this one will be revomed
elseif strcmpi(obj.PlotOptions.TreatAs, 'streamtube')
diff --git a/plotly/plotlyfig_aux/handlegraphics/updateBubblecloud.m b/plotly/plotlyfig_aux/handlegraphics/updateBubblecloud.m
new file mode 100644
index 00000000..43646aa8
--- /dev/null
+++ b/plotly/plotlyfig_aux/handlegraphics/updateBubblecloud.m
@@ -0,0 +1,270 @@
+function updateBubblecloud(obj,~)
+
+%-AXIS INDEX-%
+axIndex = obj.getAxisIndex(obj.State.Plot(1).AssociatedAxis);
+
+%-BubbleCloud (bc) DATA STRUCTURE- %
+bcData = get(obj.State.Plot(1).Handle);
+
+%-CHECK FOR MULTIPLE AXES-%
+[xsource, ysource] = findSourceAxis(obj,axIndex);
+
+% %-AXIS DATA-%
+eval(['xaxis = obj.layout.xaxis' num2str(xsource) ';']);
+eval(['yaxis = obj.layout.yaxis' num2str(ysource) ';']);
+
+obj.layout.xaxis1.showline = true;
+obj.layout.xaxis1.zeroline = false;
+obj.layout.xaxis1.autorange = false;
+obj.layout.xaxis1.mirror = true;
+
+obj.layout.yaxis1.showline = true;
+obj.layout.yaxis1.zeroline = false;
+obj.layout.yaxis1.autorange = false;
+obj.layout.yaxis1.mirror = true;
+
+%%%%%%%%%%%%%%%
+%Useful for debugging!!!
+% obj.layout.xaxis1.tickmode='auto';
+% obj.layout.xaxis1.nticks=11;
+% obj.layout.xaxis1.showticklabels=0;
+% obj.layout.yaxis1.tickmode='auto';
+% obj.layout.yaxis1.nticks=11;
+% obj.layout.yaxis1.showticklabels=0;
+%%%%%%%%%%%%%%%
+
+% obj.layout.title.text='';
+obj.layout.margin.t=80;
+obj.layout.annotations{1}.text='';
+
+
+[sortedradii,RadiusIndex]=sort(sqrt(bcData.SizeData),'descend');
+
+sortedradii=sortedradii/max(sortedradii);
+
+ar = obj.layout.width/obj.layout.height;
+
+xIN = xaxis.domain(2) - xaxis.domain(1);
+yIN = yaxis.domain(2) - yaxis.domain(1);
+axAR = ar*xIN/yIN;
+
+if isempty(bcData.GroupData) || all(bcData.GroupData==bcData.GroupData(1))
+ XY = matlab.graphics.internal.layoutBubbleCloud(sortedradii,ar);
+ nGrps=1;
+ myIdx{1} = true(size(sortedradii));
+else
+ groups=bcData.GroupData(RadiusIndex);
+ undefined_ind=ismissing(groups);
+ grplist=unique(groups(~undefined_ind));
+ groupradius=nan(numel(grplist),1);
+ for g=1:numel(grplist)
+ gp_ind=groups==grplist(g);
+ if any(gp_ind)
+ r=sortedradii(gp_ind);
+ xy=matlab.graphics.internal.layoutBubbleCloud(r,1);
+ groupradius(g)=max(sqrt(sum(xy.^2))+r);
+ XY(1:2,gp_ind)=xy;
+ end
+ end
+
+ % Layout any nan/undefined as a separate group
+ if any(undefined_ind)
+ r=sortedradii(undefined_ind);
+ xy=matlab.graphics.internal.layoutBubbleCloud(r,1);
+ groupradius(end+1)=max(sqrt(sum(xy.^2))+r);
+ XY(1:2,undefined_ind)=xy;
+ end
+
+ % Layout the circles that contain the groups
+ groupxyr=nan(3,numel(groupradius));
+ groupxyr(3,:)=groupradius;
+ [gp_sortr,gp_sortind]=sort(groupradius,'descend');
+ groupxyr(1:2,gp_sortind)=matlab.graphics.internal.layoutBubbleCloud(gp_sortr,ar);
+
+ % Apply the group bubble position as an offset
+ for g=1:numel(grplist)
+ gp_ind=groups==grplist(g);
+ XY(1:2,gp_ind)=XY(1:2,gp_ind)+groupxyr(1:2,g);
+ end
+
+ % Offset undefined group if it exists
+ if any(undefined_ind)
+ XY(1:2,undefined_ind)=XY(1:2,undefined_ind)+groupxyr(1:2,end);
+ end
+
+ gps=unique(groups);
+ nGrps = numel(gps);
+ for i = 1:nGrps
+ gp_ind = groups == gps(i);
+ myIdx{i} = gp_ind;
+ end
+
+end
+
+xR = [min(XY(1,:)-sortedradii), max(XY(1,:)+sortedradii)];
+yR = [min(XY(2,:)-sortedradii), max(XY(2,:)+sortedradii)];
+
+xR = xR + [-0.125, 0.125]*abs(diff(xR));
+yR = yR + [-0.125, 0.125]*abs(diff(yR));
+
+dataAR = abs(diff(xR))/abs(diff(yR));
+
+if dataAR > axAR
+ amounttopad = abs(diff(yR)) * dataAR/axAR - abs(diff(yR));
+ yR = yR + [-amounttopad/2, amounttopad/2];
+else
+ amounttopad = abs(diff(xR)) * axAR/dataAR - abs(diff(xR));
+ xR = xR + [-amounttopad/2, amounttopad/2];
+end
+
+radX = (2*sortedradii * (xIN*obj.layout.width) / abs(diff(xR)));
+
+obj.layout.xaxis1.range=xR;
+
+hei = obj.layout.height;
+yCorr = -7.107E-13*hei^4 + 3.145E-09*hei^3 - 5.275E-06*hei^2 + 0.004197*hei - 1.602;
+
+% yCorr = -0.235;
+if nGrps==1
+ obj.layout.yaxis1.range = yR + [-yCorr, yCorr];
+else
+ obj.layout.yaxis1.range = yR + [0.16, -0.16];
+end
+rads=radX;
+
+for bcIndex = 1:nGrps
+ %-------------------------------------------------------------------------%
+
+ %-bc xaxis-%
+ obj.data{bcIndex}.xaxis = ['x' num2str(xsource)];
+
+ %-------------------------------------------------------------------------%
+
+ %-bc yaxis-%
+ obj.data{bcIndex}.yaxis = ['y' num2str(ysource)];
+
+ %-------------------------------------------------------------------------%
+
+ %-bc type-%
+ obj.data{bcIndex}.type = 'scatter';
+
+ %-------------------------------------------------------------------------%
+
+ %-bc mode-%
+ obj.data{bcIndex}.mode = 'markers+text';
+
+ %-------------------------------------------------------------------------%
+
+ %-bc visible-%
+ obj.data{bcIndex}.visible = strcmp(bcData.Visible,'on');
+
+ %-------------------------------------------------------------------------%
+
+ labels = bcData.LabelData(RadiusIndex(myIdx{bcIndex}));
+ obj.data{bcIndex}.text = arrayfun(@(x) {char(x)}, labels);
+ obj.data{bcIndex}.textfont.family = matlab2plotlyfont(bcData.FontName);
+ obj.data{bcIndex}.textfont.color = sprintf('rgb(%i,%i,%i)',255*bcData.FontColor);
+ obj.data{bcIndex}.textfont.size = bcData.FontSize*1.5;
+
+ %-------------------------------------------------------------------------%
+
+ if isempty(bcData.SizeVariable)
+ bcData.SizeVariable='Size';
+ end
+ if isempty(bcData.LabelVariable)
+ bcData.LabelVariable='Label';
+ end
+ if isempty(bcData.GroupVariable)
+ bcData.GroupVariable='Group';
+ end
+
+ if nGrps>1
+ obj.data{bcIndex}.hovertemplate = sprintf('%s: %%{hovertext}
%s: %%{text}',bcData.SizeVariable,bcData.LabelVariable);
+ j = find(myIdx{bcIndex});
+ obj.data{bcIndex}.name = char(bcData.GroupData(RadiusIndex(j(1))));
+ obj.data{bcIndex}.hovertext = arrayfun(@(x,y) {num2str(x)}, bcData.SizeData(RadiusIndex(myIdx{bcIndex})), 'UniformOutput',false);
+ else
+ obj.data{bcIndex}.hovertemplate = sprintf('%s: %%{hovertext}
%s: %%{text}',bcData.SizeVariable,bcData.LabelVariable);
+ obj.data{bcIndex}.hovertext = arrayfun(@(x) {num2str(x)}, bcData.SizeData(RadiusIndex(myIdx{bcIndex})));
+ end
+
+ %-------------------------------------------------------------------------%
+
+ obj.data{bcIndex}.x = XY(1,myIdx{bcIndex});
+
+ %---------------------------------------------------------------------%
+
+ obj.data{bcIndex}.y = XY(2,myIdx{bcIndex});
+
+ %---------------------------------------------------------------------%
+
+ %-bc showlegend-%
+ try
+ leg = get(bcData.Annotation);
+ catch
+ leg=[];
+ end
+ if ~isempty(leg)
+ legInfo = get(leg.LegendInformation);
+
+ switch legInfo.IconDisplayStyle
+ case 'on'
+ showleg = true;
+ case 'off'
+ showleg = false;
+ end
+ end
+
+ if isfield(bcData,'ZData')
+ if isempty(bcData.ZData)
+ obj.data{bcIndex}.showlegend = showleg;
+ end
+ end
+
+ %---------------------------------------------------------------------%
+
+ %-line color-%
+ if length(bcData) > 1
+ obj.data{bcIndex}.marker.line.color{m} = childmarker.line.color{1};
+ else
+ col=uint8(bcData.EdgeColor*255);
+ obj.data{bcIndex}.marker.line.color = sprintf('rgb(%i,%i,%i)',col);
+ end
+
+ %---------------------------------------------------------------------%
+
+ %-marker color-%
+ col=uint8(bcData.ColorOrder(bcIndex,:)*255);
+ obj.data{bcIndex}.marker.color = sprintf('rgb(%i,%i,%i)',col);
+
+ %---------------------------------------------------------------------%
+
+ %-sizeref-%
+ obj.data{bcIndex}.marker.sizeref = 1;
+
+ %---------------------------------------------------------------------%
+
+ %-sizemode-%
+ obj.data{bcIndex}.marker.sizemode = 'diameter';
+
+ %---------------------------------------------------------------------%
+
+ %-symbol-%
+ obj.data{bcIndex}.marker.symbol = 'circle';
+
+ %---------------------------------------------------------------------%
+
+ %-size-%
+ obj.data{bcIndex}.marker.size = rads(myIdx{bcIndex});
+
+ %---------------------------------------------------------------------%
+
+ %-line width-%
+ obj.data{bcIndex}.marker.line.width = 1.5;
+
+ %---------------------------------------------------------------------%
+
+end
+
+end
+
diff --git a/plotly/plotlyfig_aux/helpers/extractAxisData.m b/plotly/plotlyfig_aux/helpers/extractAxisData.m
index a87d8b61..e7774c06 100644
--- a/plotly/plotlyfig_aux/helpers/extractAxisData.m
+++ b/plotly/plotlyfig_aux/helpers/extractAxisData.m
@@ -7,8 +7,15 @@
%-------------------------------------------------------------------------%
%-axis-side-%
-axis.side = eval(['axis_data.' axisName 'AxisLocation;']);
-
+try
+ axis.side = eval(['axis_data.' axisName 'AxisLocation;']);
+catch
+ if axisName == 'X'
+ axis.side = 'bottom';
+ elseif axisName == 'Y'
+ axis.side = 'left';
+ end
+end
%-------------------------------------------------------------------------%
%-axis zeroline-%
@@ -36,16 +43,23 @@
%-------------------------------------------------------------------------%
-ticklength = min(obj.PlotlyDefaults.MaxTickLength,...
- max(axis_data.TickLength(1)*axis_data.Position(3)*obj.layout.width,...
- axis_data.TickLength(1)*axis_data.Position(4)*obj.layout.height));
+try
+ ticklength = min(obj.PlotlyDefaults.MaxTickLength,...
+ max(axis_data.TickLength(1)*axis_data.Position(3)*obj.layout.width,...
+ axis_data.TickLength(1)*axis_data.Position(4)*obj.layout.height));
%-axis ticklen-%
-axis.ticklen = ticklength;
-
+ axis.ticklen = ticklength;
+catch
+ axis.ticklen = 0;
+end
%-------------------------------------------------------------------------%
-col = eval(['255*axis_data.' axisName 'Color;']);
-axiscol = ['rgb(' num2str(col(1)) ',' num2str(col(2)) ',' num2str(col(3)) ')'];
+try
+ col = eval(['255*axis_data.' axisName 'Color;']);
+catch
+ col = [0,0,0];
+end
+axiscol = sprintf('rgb(%i,%i,%i)',col);
%-axis linecolor-%
axis.linecolor = axiscol;
@@ -57,29 +71,38 @@
axis.gridcolor = axiscol;
%-------------------------------------------------------------------------%
-
-if strcmp(axis_data.XGrid, 'on') || strcmp(axis_data.XMinorGrid, 'on')
- %-axis show grid-%
- axis.showgrid = true;
-else
- axis.showgrid = false;
+try
+ if strcmp(axis_data.XGrid, 'on') || strcmp(axis_data.XMinorGrid, 'on')
+ %-axis show grid-%
+ axis.showgrid = true;
+ else
+ axis.showgrid = false;
+ end
+catch
+ axis.showgrid = false;
end
-
%-------------------------------------------------------------------------%
-grid = eval(['axis_data.' axisName 'Grid;']);
-minorGrid = eval(['axis_data.' axisName 'MinorGrid;']);
+try
+ grid = eval(['axis_data.' axisName 'Grid;']);
+ minorGrid = eval(['axis_data.' axisName 'MinorGrid;']);
-if strcmp(grid, 'on') || strcmp(minorGrid, 'on')
- %-axis show grid-%
- axis.showgrid = true;
-else
+ if strcmp(grid, 'on') || strcmp(minorGrid, 'on')
+ %-axis show grid-%
+ axis.showgrid = true;
+ else
+ axis.showgrid = false;
+ end
+catch
axis.showgrid = false;
end
%-------------------------------------------------------------------------%
-
-linewidth = max(1,axis_data.LineWidth*obj.PlotlyDefaults.AxisLineIncreaseFactor);
+try
+ linewidth = max(1,axis_data.LineWidth*obj.PlotlyDefaults.AxisLineIncreaseFactor);
+catch
+ linewidth = 0;
+end
%-axis line width-%
axis.linewidth = linewidth;
@@ -91,12 +114,21 @@
%-------------------------------------------------------------------------%
%-axis type-%
-axis.type = eval(['axis_data.' axisName 'Scale']);
+try
+ axis.type = eval(['axis_data.' axisName 'Scale']);
+catch
+ axis.type = 'linear';
+end
%-------------------------------------------------------------------------%
%-axis showtick labels / ticks-%
-tick = eval(['axis_data.' axisName 'Tick']);
+try
+ tick = eval(['axis_data.' axisName 'Tick']);
+catch
+ tick=[];
+end
+
if isempty(tick)
%-axis ticks-%
@@ -107,13 +139,16 @@
axis.autorange = true;
%---------------------------------------------------------------------%
-
- switch axis_data.Box
- case 'on'
- %-axis mirror-%
- axis.mirror = true;
- case 'off'
- axis.mirror = false;
+ try
+ switch axis_data.Box
+ case 'on'
+ %-axis mirror-%
+ axis.mirror = true;
+ case 'off'
+ axis.mirror = false;
+ end
+ catch
+ axis.mirror = true;
end
%---------------------------------------------------------------------%
@@ -295,50 +330,56 @@
end
%-------------------------------------------------------------------------%
-
-Dir = eval(['axis_data.' axisName 'Dir;']);
+try
+ Dir = eval(['axis_data.' axisName 'Dir;']);
+catch
+ Dir = '';
+end
if strcmp(Dir,'reverse')
axis.range = [axis.range(2) axis.range(1)];
end
%-------------------------------LABELS------------------------------------%
+try
+ label = eval(['axis_data.' axisName 'Label;']);
+catch
+ label=[];
+end
+if ~isempty(label)
+ label_data = get(label);
-label = eval(['axis_data.' axisName 'Label;']);
-
-label_data = get(label);
-
-%STANDARDIZE UNITS
-fontunits = get(label,'FontUnits');
-set(label,'FontUnits','points');
+ %STANDARDIZE UNITS
+ fontunits = get(label,'FontUnits');
+ set(label,'FontUnits','points');
-%-------------------------------------------------------------------------%
+ %-------------------------------------------------------------------------%
-%-title-%
-if ~isempty(label_data.String)
- axis.title = parseString(label_data.String,label_data.Interpreter);
-end
-
-%-------------------------------------------------------------------------%
+ %-title-%
+ if ~isempty(label_data.String)
+ axis.title = parseString(label_data.String,label_data.Interpreter);
+ end
-%-axis title font color-%
-col = 255*label_data.Color;
-axis.titlefont.color = ['rgb(' num2str(col(1)) ',' num2str(col(2)) ',' num2str(col(3)) ')'];
+ %-------------------------------------------------------------------------%
-%-------------------------------------------------------------------------%
+ %-axis title font color-%
+ col = 255*label_data.Color;
+ axis.titlefont.color = ['rgb(' num2str(col(1)) ',' num2str(col(2)) ',' num2str(col(3)) ')'];
-%-axis title font size-%
-axis.titlefont.size = label_data.FontSize;
+ %-------------------------------------------------------------------------%
-%-------------------------------------------------------------------------%
+ %-axis title font size-%
+ axis.titlefont.size = label_data.FontSize;
-%-axis title font family-%
-axis.titlefont.family = matlab2plotlyfont(label_data.FontName);
+ %-------------------------------------------------------------------------%
-%-------------------------------------------------------------------------%
+ %-axis title font family-%
+ axis.titlefont.family = matlab2plotlyfont(label_data.FontName);
-%REVERT UNITS
-set(label,'FontUnits',fontunits);
+ %-------------------------------------------------------------------------%
+ %REVERT UNITS
+ set(label,'FontUnits',fontunits);
+end
%-------------------------------------------------------------------------%
if strcmp(axis_data.Visible,'on')
@@ -351,12 +392,6 @@
axis.showticklabels = false;
%-axis ticks-%
axis.ticks = '';
- %-axis showline-%
- axis.showline = false;
- %-axis showticklabels-%
- axis.showticklabels = false;
- %-axis ticks-%
- axis.ticks = '';
end
%-------------------------------------------------------------------------%