From 0b7eebeaf883f81bb5fdede8db567e3bd11a9700 Mon Sep 17 00:00:00 2001 From: Gilberto Galvis Date: Tue, 17 Aug 2021 08:59:48 -0400 Subject: [PATCH 1/3] fix issue #204 --- .../handlegraphics/updateHeatmap.m | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 plotly/plotlyfig_aux/handlegraphics/updateHeatmap.m diff --git a/plotly/plotlyfig_aux/handlegraphics/updateHeatmap.m b/plotly/plotlyfig_aux/handlegraphics/updateHeatmap.m new file mode 100644 index 00000000..9fad55fd --- /dev/null +++ b/plotly/plotlyfig_aux/handlegraphics/updateHeatmap.m @@ -0,0 +1,52 @@ +function obj = updateHeatmap(obj,heatIndex) + +%-------------------------------------------------------------------------% + +%-HEATMAP DATA STRUCTURE- % +heat_data = get(obj.State.Plot(heatIndex).Handle); +%-------------------------------------------------------------------------% + +%-heatmap type-% +obj.data{heatIndex}.type = 'heatmap'; + +%-------------------------------------------------------------------------% + +%-format data-% +obj.data{heatIndex}.x = heat_data.XData; +obj.data{heatIndex}.y = heat_data.YData; +obj.data{heatIndex}.z = heat_data.ColorData(end:-1:1, :); + +%-------------------------------------------------------------------------% + +%-heatmap colorscale-% +cmap = heat_data.Colormap; +len = length(cmap)-1; + +for c = 1: length(cmap) + col = 255 * cmap(c, :); + obj.data{heatIndex}.colorscale{c} = { (c-1)/len , ['rgb(' num2str(col(1)) ',' num2str(col(2)) ',' num2str(col(3)) ')' ] }; +end + +%-------------------------------------------------------------------------% + +%-setting plot-% +obj.data{heatIndex}.hoverinfo = 'text'; +obj.data{heatIndex}.text = heat_data.ColorData(end:-1:1, :); +obj.data{heatIndex}.hoverlabel.bgcolor = 'white'; + +%-------------------------------------------------------------------------% + +%-show colorbar-% +obj.data{heatIndex}.showscale = false; +if strcmpi(heat_data.ColorbarVisible, 'on') + obj.data{heatIndex}.showscale = true; +end + +%-------------------------------------------------------------------------% + +%-hist visible-% +obj.data{heatIndex}.visible = strcmp(heat_data.Visible,'on'); + +%-------------------------------------------------------------------------% + +end From 276db0f4bc6094fee8a52483dd8869d422bead3a Mon Sep 17 00:00:00 2001 From: Gilberto Galvis Date: Tue, 17 Aug 2021 11:00:32 -0400 Subject: [PATCH 2/3] fix issue #284 --- plotly/plotlyfig.m | 1 + plotly/plotlyfig_aux/core/updateData.m | 6 +- .../handlegraphics/updateImage3D.m | 197 ++++++++++++++++++ .../handlegraphics/updateSurfaceplot.m | 38 +++- 4 files changed, 232 insertions(+), 10 deletions(-) create mode 100644 plotly/plotlyfig_aux/handlegraphics/updateImage3D.m diff --git a/plotly/plotlyfig.m b/plotly/plotlyfig.m index 15a77540..b22da5f8 100644 --- a/plotly/plotlyfig.m +++ b/plotly/plotlyfig.m @@ -61,6 +61,7 @@ obj.PlotOptions.TriangulatePatch = false; obj.PlotOptions.StripMargins = false; obj.PlotOptions.TreatAs = '_'; + obj.PlotOptions.Image3D = false; % offline options obj.PlotOptions.Offline = true; diff --git a/plotly/plotlyfig_aux/core/updateData.m b/plotly/plotlyfig_aux/core/updateData.m index da579f05..9967cdad 100644 --- a/plotly/plotlyfig_aux/core/updateData.m +++ b/plotly/plotlyfig_aux/core/updateData.m @@ -25,7 +25,11 @@ case 'heatmap' updateHeatmap(obj, dataIndex); case 'image' - updateImage(obj, dataIndex); + if ~obj.PlotOptions.Image3D + updateImage(obj, dataIndex); + else + updateImage3D(obj, dataIndex); + end case 'line' updateLineseries(obj, dataIndex); case 'categoricalhistogram' diff --git a/plotly/plotlyfig_aux/handlegraphics/updateImage3D.m b/plotly/plotlyfig_aux/handlegraphics/updateImage3D.m new file mode 100644 index 00000000..050d22d8 --- /dev/null +++ b/plotly/plotlyfig_aux/handlegraphics/updateImage3D.m @@ -0,0 +1,197 @@ +function obj = updateImage3D(obj, imageIndex) + +% AS SURFACE +% z: ...[DONE] +% x: ...[DONE] +% y: ...[DONE] +% name: ...[DONE] +% zauto: ...[DONE] +% zmin: ...[DONE] +% zmax: ...[DONE] +% colorscale: ...[DONE] +% reversescale: ...[DONE] +% showscale: ...[DONE] +% colorbar: ...[HANDLED BY COLORBAR] +% zsmooth: ...[NOT SUPPORTED BY MATLAB] +% opacity: ---[TODO] +% xaxis: ...[DONE] +% yaxis: ...[DONE] +% showlegend: ...[DONE] +% stream: ...[HANDLED BY PLOTLYSTREAM] +% visible: ...[DONE] +% x0: ...[NOT SUPPORTED IN MATLAB] +% dx: ...[NOT SUPPORTED IN MATLAB] +% y0: ...[NOT SUPPORTED IN MATLAB] +% dy: ...[NOT SUPPORTED IN MATLAB] +% xtype: ...[NOT SUPPORTED IN MATLAB] +% ytype: ...[NOT SUPPORTED IN MATLAB] +% type: ...[DONE] + +%-FIGURE STRUCTURE-% +figure_data = get(obj.State.Figure.Handle); + +%-AXIS STRUCTURE-% +axis_data = get(obj.State.Plot(imageIndex).AssociatedAxis); + +%-AXIS INDEX-% +axIndex = obj.getAxisIndex(obj.State.Plot(imageIndex).AssociatedAxis); + +%-CHECK FOR MULTIPLE AXES-% +[xsource, ysource] = findSourceAxis(obj,axIndex); + +%-IMAGE DATA STRUCTURE- % +image_data = get(obj.State.Plot(imageIndex).Handle); + +%-AXIS DATA-% +eval(['xaxis = obj.layout.xaxis' num2str(xsource) ';']); +eval(['yaxis = obj.layout.yaxis' num2str(ysource) ';']); + +%-------------------------------------------------------------------------% + +%-image xaxis-% +obj.data{imageIndex}.xaxis = ['x' num2str(xsource)]; + +%-------------------------------------------------------------------------% + +%-image yaxis-% +obj.data{imageIndex}.yaxis = ['y' num2str(ysource)]; + +%-------------------------------------------------------------------------% + +%-image type-% +obj.data{imageIndex}.type = 'surface'; + +%-------------------------------------------------------------------------% + +%-format x an y data-% +x = image_data.XData; +y = image_data.YData; +cdata = image_data.CData; + +if isvector(x) + if size(x,2) == 2 + x = linspace(x(1), x(2), size(cdata,2)); + end + + if size(y,2) == 2 + y = linspace(y(1), y(2), size(cdata,1)); + end + + [x, y] = meshgrid(x, y); +end + +%-------------------------------------------------------------------------% + +%-surface x-% +obj.data{imageIndex}.x = x; + +%-------------------------------------------------------------------------% + +%-surface x-% +obj.data{imageIndex}.y = y; + +%-------------------------------------------------------------------------% + +%-surface z-% +isrgbimg = (size(image_data.CData,3) > 1); + +if isrgbimg + [IND,colormap] = rgb2ind(cdata, 256); + obj.data{imageIndex}.z = IND; +else + obj.data{imageIndex}.z = zeros(size(cdata)); +end + +%-------------------------------------------------------------------------% + +%-surface coloring-% +obj.data{imageIndex}.surfacecolor = cdata; + +%-------------------------------------------------------------------------% + +%-surface setting-% +obj.layout.scene.aspectmode = 'cube'; + +%-------------------------------------------------------------------------% + +%-image name-% +try + obj.data{imageIndex}.name = image_data.DisplayName; +catch + obj.data{imageIndex}.name = ''; +end + +%-------------------------------------------------------------------------% + +%-set the opacity-% +obj.data{imageIndex}.opacity = image_data.AlphaData; + +%-------------------------------------------------------------------------% + +%-image visible-% +obj.data{imageIndex}.visible = strcmp(image_data.Visible,'on'); + +%-------------------------------------------------------------------------% + +%-image showscale-% +obj.data{imageIndex}.showscale = false; + +%-------------------------------------------------------------------------% + +%-image zauto-% +obj.data{imageIndex}.zauto = false; + +%-------------------------------------------------------------------------% + +%-image zmin-% +obj.data{imageIndex}.zmin = axis_data.CLim(1); + +%-------------------------------------------------------------------------% + +%-image zmax-% +if ~strcmpi(image_data.CDataMapping, 'direct') + obj.data{imageIndex}.zmax = axis_data.CLim(2); +else + obj.data{imageIndex}.zmax = 255; +end + +%-------------------------------------------------------------------------% + +%-COLORSCALE (ASSUMES IMAGE CDATAMAP IS 'SCALED')-% + +%-image colorscale-% + +if ~isrgbimg + colormap = figure_data.Colormap; +end + +len = length(colormap) - 1; + +for c = 1:size(colormap, 1) + col = 255*(colormap(c,:)); + obj.data{imageIndex}.colorscale{c} = {(c-1)/len, ['rgb(' num2str(col(1)) ',' num2str(col(2)) ',' num2str(col(3)) ')']}; +end + +%-------------------------------------------------------------------------% + +%-image showlegend-% +try + leg = get(image_data.Annotation); + legInfo = get(leg.LegendInformation); + + switch legInfo.IconDisplayStyle + case 'on' + showleg = true; + case 'off' + showleg = false; + end + + obj.data{imageIndex}.showlegend = showleg; +catch + %TODO to future +end + +%-------------------------------------------------------------------------% + +end + diff --git a/plotly/plotlyfig_aux/handlegraphics/updateSurfaceplot.m b/plotly/plotlyfig_aux/handlegraphics/updateSurfaceplot.m index de878305..f291773c 100644 --- a/plotly/plotlyfig_aux/handlegraphics/updateSurfaceplot.m +++ b/plotly/plotlyfig_aux/handlegraphics/updateSurfaceplot.m @@ -29,40 +29,57 @@ % check for 3D if any(nonzeros(image_data.ZData)) + %---------------------------------------------------------------------% + %-surface type-% obj.data{surfaceIndex}.type = 'surface'; %---------------------------------------------------------------------% + %-format x an y data-% + x = image_data.XData; + y = image_data.YData; + cdata = image_data.CData; + if isvector(x) + [x, y] = meshgrid(x,y); + end + + %---------------------------------------------------------------------% + %-surface x-% - obj.data{surfaceIndex}.x = image_data.XData; + obj.data{surfaceIndex}.x = x; %---------------------------------------------------------------------% %-surface y-% - obj.data{surfaceIndex}.y = image_data.YData; + obj.data{surfaceIndex}.y = y; %---------------------------------------------------------------------% %-surface z-% obj.data{surfaceIndex}.z = image_data.ZData; + %---------------------------------------------------------------------% + + %-if image comes would a 3D plot-% + obj.PlotOptions.Image3D = true; + %---------------------------------------------------------------------% %- setting grid mesh by default -% % x-direction - xmin = min(image_data.XData(:)); - xmax = max(image_data.XData(:)); - xsize = (xmax - xmin) / (size(image_data.XData, 2) - 1); + xmin = min(x(:)); + xmax = max(x(:)); + xsize = (xmax - xmin) / (size(x, 2)); obj.data{surfaceIndex}.contours.x.start = xmin; obj.data{surfaceIndex}.contours.x.end = xmax; obj.data{surfaceIndex}.contours.x.size = xsize; obj.data{surfaceIndex}.contours.x.show = true; obj.data{surfaceIndex}.contours.x.color = 'black'; % y-direction - ymin = min(image_data.YData(:)); - ymax = max(image_data.YData(:)); - ysize = (ymax - ymin) / (size(image_data.YData, 2)); + ymin = min(y(:)); + ymax = max(y(:)); + ysize = (ymax - ymin) / (size(y, 1)); obj.data{surfaceIndex}.contours.y.start = ymin; obj.data{surfaceIndex}.contours.y.end = ymax; obj.data{surfaceIndex}.contours.y.size = ysize; @@ -94,7 +111,10 @@ obj.data{surfaceIndex}.colorscale{c} = { (c-1)/len , ['rgb(' num2str(col(1)) ',' num2str(col(2)) ',' num2str(col(3)) ')' ] }; end -obj.data{surfaceIndex}.surfacecolor = image_data.CData; +%-------------------------------------------------------------------------% + +%-surface coloring-% +obj.data{surfaceIndex}.surfacecolor = cdata; %-------------------------------------------------------------------------% From 226127d766a1c0e295c712d598c92cbe1d39cf17 Mon Sep 17 00:00:00 2001 From: Gilberto Galvis Date: Tue, 17 Aug 2021 21:36:27 -0400 Subject: [PATCH 3/3] fix issue #259 --- plotly/plotlyfig.m | 1 + plotly/plotlyfig_aux/core/updateData.m | 6 +- .../handlegraphics/updateContourProjection.m | 230 ++++++++++++++++++ .../handlegraphics/updateSurfaceplot.m | 7 +- 4 files changed, 241 insertions(+), 3 deletions(-) create mode 100644 plotly/plotlyfig_aux/handlegraphics/updateContourProjection.m diff --git a/plotly/plotlyfig.m b/plotly/plotlyfig.m index b22da5f8..704e215d 100644 --- a/plotly/plotlyfig.m +++ b/plotly/plotlyfig.m @@ -62,6 +62,7 @@ obj.PlotOptions.StripMargins = false; obj.PlotOptions.TreatAs = '_'; obj.PlotOptions.Image3D = false; + obj.PlotOptions.ContourProjection = false; % offline options obj.PlotOptions.Offline = true; diff --git a/plotly/plotlyfig_aux/core/updateData.m b/plotly/plotlyfig_aux/core/updateData.m index 9967cdad..833327da 100644 --- a/plotly/plotlyfig_aux/core/updateData.m +++ b/plotly/plotlyfig_aux/core/updateData.m @@ -70,7 +70,11 @@ case 'baseline' updateBaseline(obj, dataIndex); case {'contourgroup','contour'} - updateContourgroup(obj,dataIndex); + if ~obj.PlotOptions.ContourProjection + updateContourgroup(obj,dataIndex); + else + updateContourProjection(obj,dataIndex); + end case 'functioncontour' updateFunctionContour(obj,dataIndex); case 'errorbar' diff --git a/plotly/plotlyfig_aux/handlegraphics/updateContourProjection.m b/plotly/plotlyfig_aux/handlegraphics/updateContourProjection.m new file mode 100644 index 00000000..6ad5051c --- /dev/null +++ b/plotly/plotlyfig_aux/handlegraphics/updateContourProjection.m @@ -0,0 +1,230 @@ +function obj = updateContourProjection(obj,contourIndex) + +%-FIGURE DATA STRUCTURE-% +figure_data = get(obj.State.Figure.Handle); + +%-AXIS INDEX-% +axIndex = obj.getAxisIndex(obj.State.Plot(contourIndex).AssociatedAxis); + +%-AXIS DATA STRUCTURE-% +axis_data = get(obj.State.Plot(contourIndex).AssociatedAxis); + +%-PLOT DATA STRUCTURE- % +contour_data = get(obj.State.Plot(contourIndex).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) ';']); + +%-------------------------------------------------------------------------% + +%-contour xaxis-% +obj.data{contourIndex}.xaxis = ['x' num2str(xsource)]; + +%-------------------------------------------------------------------------% + +%-contour yaxis-% +obj.data{contourIndex}.yaxis = ['y' num2str(ysource)]; + +%-------------------------------------------------------------------------% + +%-contour name-% +obj.data{contourIndex}.name = contour_data.DisplayName; + +%-------------------------------------------------------------------------% + +%-setting the plot-% +xdata = contour_data.XData; +ydata = contour_data.YData; +zdata = contour_data.ZData; + +if isvector(zdata) + + %-contour type-% + obj.data{contourIndex}.type = 'contour'; + + %-contour x data-% + if ~isvector(x) + obj.data{contourIndex}.xdata = xdata(1,:); + else + obj.data{contourIndex}.xdata = xdata; + end + + %-contour y data-% + if ~isvector(y) + obj.data{contourIndex}.ydata = ydata'; + else + obj.data{contourIndex}.ydata = ydata'; + end + + %-contour z data-% + obj.data{contourIndex}.z = zdata; + +else + + %-contour type-% + obj.data{contourIndex}.type = 'surface'; + + %-contour x and y data +% [xmesh, ymesh] = meshgrid(xdata, ydata); + obj.data{contourIndex}.x = xdata; + obj.data{contourIndex}.y = ydata; + + %-contour z data-% + obj.data{contourIndex}.z = zdata;%-2*ones(size(zdata)); + + %-setting for contour lines z-direction-% + obj.data{contourIndex}.contours.z.start = contour_data.LevelList(1); + obj.data{contourIndex}.contours.z.end = contour_data.LevelList(end); + obj.data{contourIndex}.contours.z.size = contour_data.LevelStep; + obj.data{contourIndex}.contours.z.show = true; + obj.data{contourIndex}.contours.z.usecolormap = true; + obj.data{contourIndex}.hidesurface = true; + obj.data{contourIndex}.surfacecolor = zdata; + + obj.data{contourIndex}.contours.z.project.x = true; + obj.data{contourIndex}.contours.z.project.y = true; + obj.data{contourIndex}.contours.z.project.z = true; + +end + +%-------------------------------------------------------------------------% + +%-contour x type-% + +obj.data{contourIndex}.xtype = 'array'; + +%-------------------------------------------------------------------------% + +%-contour y type-% + +obj.data{contourIndex}.ytype = 'array'; + +%-------------------------------------------------------------------------% + +%-contour visible-% + +obj.data{contourIndex}.visible = strcmp(contour_data.Visible,'on'); + +%-------------------------------------------------------------------------% + +%-contour showscale-% +obj.data{contourIndex}.showscale = false; + +%-------------------------------------------------------------------------% + +%-zauto-% +obj.data{contourIndex}.zauto = false; + +%-------------------------------------------------------------------------% + +%-zmin-% +obj.data{contourIndex}.zmin = axis_data.CLim(1); + +%-------------------------------------------------------------------------% + +%-zmax-% +obj.data{contourIndex}.zmax = axis_data.CLim(2); + +%-------------------------------------------------------------------------% + +%-colorscale (ASSUMES PATCH CDATAMAP IS 'SCALED')-% +colormap = figure_data.Colormap; + +for c = 1:size((colormap),1) + col = 255*(colormap(c,:)); + obj.data{contourIndex}.colorscale{c} = {(c-1)/(size(colormap,1)-1), ['rgb(' num2str(col(1)) ',' num2str(col(2)) ',' num2str(col(3)) ')']}; +end + +%-------------------------------------------------------------------------% + +%-contour reverse scale-% +obj.data{contourIndex}.reversescale = false; + +%-------------------------------------------------------------------------% + +%-autocontour-% +obj.data{contourIndex}.autocontour = false; + +%-------------------------------------------------------------------------% + +%-contour contours-% + +%-coloring-% +switch contour_data.Fill + case 'off' + obj.data{contourIndex}.contours.coloring = 'lines'; + case 'on' + obj.data{contourIndex}.contours.coloring = 'fill'; +end + +%-start-% +obj.data{contourIndex}.contours.start = contour_data.TextList(1); + +%-end-% +obj.data{contourIndex}.contours.end = contour_data.TextList(end); + +%-step-% +obj.data{contourIndex}.contours.size = diff(contour_data.TextList(1:2)); + +%-------------------------------------------------------------------------% + +if(~strcmp(contour_data.LineStyle,'none')) + + %-contour line colour-% + if isnumeric(contour_data.LineColor) + col = 255*contour_data.LineColor; + obj.data{contourIndex}.line.color = ['rgb(' num2str(col(1)) ',' num2str(col(2)) ',' num2str(col(3)) ')']; + else + obj.data{contourIndex}.line.color = 'rgba(0,0,0,0)'; + end + + %-contour line width-% + obj.data{contourIndex}.line.width = contour_data.LineWidth; + + %-contour line dash-% + switch contour_data.LineStyle + case '-' + LineStyle = 'solid'; + case '--' + LineStyle = 'dash'; + case ':' + LineStyle = 'dot'; + case '-.' + LineStyle = 'dashdot'; + end + + obj.data{contourIndex}.line.dash = LineStyle; + + %-contour smoothing-% + obj.data{contourIndex}.line.smoothing = 0; + +else + + %-contours showlines-% + obj.data{contourIndex}.contours.showlines = false; + +end + +%-------------------------------------------------------------------------% + +%-contour showlegend-% + +leg = get(contour_data.Annotation); +legInfo = get(leg.LegendInformation); + +switch legInfo.IconDisplayStyle + case 'on' + showleg = true; + case 'off' + showleg = false; +end + +obj.data{contourIndex}.showlegend = showleg; + +%-------------------------------------------------------------------------% + +end diff --git a/plotly/plotlyfig_aux/handlegraphics/updateSurfaceplot.m b/plotly/plotlyfig_aux/handlegraphics/updateSurfaceplot.m index f291773c..c58014fc 100644 --- a/plotly/plotlyfig_aux/handlegraphics/updateSurfaceplot.m +++ b/plotly/plotlyfig_aux/handlegraphics/updateSurfaceplot.m @@ -64,13 +64,16 @@ %-if image comes would a 3D plot-% obj.PlotOptions.Image3D = true; + %-if contour comes would a ContourProjection-% + obj.PlotOptions.ContourProjection = true; + %---------------------------------------------------------------------% %- setting grid mesh by default -% % x-direction xmin = min(x(:)); xmax = max(x(:)); - xsize = (xmax - xmin) / (size(x, 2)); + xsize = (xmax - xmin) / (size(x, 2)-1); obj.data{surfaceIndex}.contours.x.start = xmin; obj.data{surfaceIndex}.contours.x.end = xmax; obj.data{surfaceIndex}.contours.x.size = xsize; @@ -79,7 +82,7 @@ % y-direction ymin = min(y(:)); ymax = max(y(:)); - ysize = (ymax - ymin) / (size(y, 1)); + ysize = (ymax - ymin) / (size(y, 1)-1); obj.data{surfaceIndex}.contours.y.start = ymin; obj.data{surfaceIndex}.contours.y.end = ymax; obj.data{surfaceIndex}.contours.y.size = ysize;