210 SaveFont =
struct(
"'FontWeight','bold','FontSize',16");
349 s =
get(0,
" MonitorPositions ");
383 tag = strrep(tag,
" . ",
" _ ");
395 fpos =
get(0,
" DefaultFigurePosition ");
398 this.
Figures(end+1) = figure(
" Position ",fpos,
" Tag ",tag,...
399 " Units ",
" pixels ");
405 this.cnt= this.cnt + numsubplots;
406 if isempty(this.
Figures) || this.cnt > this.rows*this.cols
407 this.nextFigure(numsubplots,
" Position ",fpos,
" Tag ",tag,...
408 " Units ",
" pixels ");
413 figure(
get(this.curax,
" Parent "));
416 ax_handle = subplot(this.rows, this.cols, ...
417 (this.cnt-numsubplots+1):this.cnt,
" Tag ", tag);
419 this.curax= ax_handle;
420 this.donelast=
false;
450 fprintf(2,
" No figures exist yet within the PlotManager. Nothing to copy.\n ");
453 error(
" copyFigure works only in single plot mode. ");
458 error(
" nr must not be empty and within the range 1 to %d ",length(this.
Figures));
462 newtag = [
get(s,
" Tag ")
" _copy "];
464 f = figure(
" Position ",
get(s,
" Position "),
" Tag ",newtag);
467 h = copyobj(
get(s,
" Children "),f);
468 h =
findobj(h,
" Tag ",,
" Type ",
" axes ");
486 if ~isempty(tagextra)
487 tagextra = [
" _ " tagextra];
490 area = [
reshape(area,1,2) NaN NaN];
494 error(
" Zooming only possible for Single mode yet. ");
496 error(
" nr must not be empty and within the range 1 to %d ",length(this.
Figures));
501 useold = isnan(area);
504 oldarea = [
get(h,
" XLim ")
get(h,
" YLim ")];
505 area = useold.*oldarea + (~useold).*area;
508 delete(
findobj(
get(this.
Figures(end),
" Children "),
" Tag ",
" legend "));
511 this.checkTickMarks(h);
532 ip.addParamValue(
'Format',this.
SaveFormats,@(arg)(ischar(arg) || iscellstr(arg)) && ~isempty(arg));
533 ip.addParamValue(
'Close',
false,@islogical);
534 ip.addParamValue(
'Selection',1:length(this.
Figures),@isvector);
535 ip.addParamValue(
'SeparateLegends',
false,@(arg)islogical(arg) && isvector(arg));
536 ip.addParamValue(
'XArgs',{},@iscellstr);
540 if exist(folder,
" file ") ~= 7
543 ip.parse(varargin[:]);
545 selection = res.Selection;
546 separate_legends = res.SeparateLegends;
547 if isscalar(separate_legends)
548 separate_legends = repmat(separate_legends,1,length(selection));
549 elseif ~
all(size(selection) == size(separate_legends))
550 error(
" If a separate legends parameter is passed, it must match the selection parameter size. ");
561 n = length(selection);
563 if length(format) > 1
564 fmtstr = [sprintf(
" %s, ",format[1:end-1]) format[end]];
566 fprintf(
" Saving %d current figures as '%s' in %s... ", n, fmtstr, folder);
568 h = this.
Figures(selection(idx));
571 fname =
get(h,
" Tag ");
575 fname = sprintf(
" figure_%d ",idx);
577 [oldtitles, oldfonts] = this.preSave(h);
580 if separate_legends(idx)
581 legends =
findobj(h,
" tag ",
" legend ");
582 lfh = zeros(1,length(legends));
583 for lidx = 1:length(legends)
584 lfh(lidx) = figure(
" Visible ",
" off ",
" MenuBar ",
" none ");
585 newlh = copyobj(legends(lidx),lfh(lidx));
586 set(newlh,
" Box ",
" off ");
587 set(legends(lidx),
" Visible ",
" off ");
590 warning(
" PlotManager:savePlots ",...
591 " No legends found for Figure %d. ",selection(idx));
599 this.saveFigure(h, fullfile(folder, fname), format, res.XArgs);
601 for lidx = 1:length(legends)
602 this.saveFigure(lfh(lidx), ...
603 fullfile(folder, sprintf(
" %s_legend%d ",fname, lidx)),...
609 for fmt = 1:length(format)
610 if exist(fullfile(folder,format[fmt]),
" file ") ~= 7
611 mkdir(fullfile(folder,format[fmt]));
613 fn = [fname
" . " format[fmt]];
615 movefile(fullfile(folder, fn), fullfile(folder,format[fmt],fn));
617 for lidx = 1:length(legends)
618 fn = sprintf(
" %s_legend%d.%s ", fname, lidx, format[fmt]);
619 movefile(fullfile(folder, fn), fullfile(folder,format[fmt],fn));
640 for lidx = 1:length(legends)
641 set(legends(lidx),
" Visible ",
" on ");
644 this.postSave(h, oldtitles, oldfonts);
646 fprintf(2,
" Warning: figure handle %d is invalid. Did you close it? ",...
650 fprintf(
" done!\n ");
682 selection = 1:length(this.
Figures);
684 for i=1:length(selection)
685 h = this.
Figures(selection(i));
686 if ishandle(h) && strcmp(
get(h,
" Type "),
" figure ")
690 if ~isempty(this.curax) && ishandle(this.curax) && strcmp(
get(this.curax,
" Type "),
" figure ")
727 if ishandle(h) && strcmp(
get(h,
" Type "),
" figure ")
728 set(h,
" Name ",name);
736 ip.addParamValue(
'Axis',
'YLim',@(arg)(ischar(arg)) && any(strcmp(arg,{
'XLim',
'YLim',
'ZLim'})));
738 ip.parse(varargin[:]);
740 lim =
get(ax_handles(1),res.Axis);
741 for k = 2:numel(ax_handles)
742 tmp =
get(ax_handles(
k),res.Axis);
743 lim(1) = min(lim(1),tmp(1));
744 lim(2) = max(lim(2),tmp(2));
746 for k = 1:numel(ax_handles)
747 set(ax_handles, res.Axis, lim);
756 #if 0 //mtoc++: 'set.SaveFormats'
772 #if 0 //mtoc++: 'set.ExportDPI'
787 function fh = nextFigure(numsubplots,
varargin) {
792 this.fignr= this.fignr + 1;
793 fh = figure(varargin[:]);
796 this.cnt= numsubplots;
800 function finishCurrent() {
805 if ~isempty(this.ncap)
808 if ~isempty(this.nxl)
811 if ~isempty(this.nyl)
814 if ~isempty(this.nleg)
815 legend(h, this.nleg[:]);
818 if ~any(strcmp(get(h,[" XLimMode "," YLimMode "," ZLimMode "])," manual "))
822 this.checkTickMarks(h);
834 function checkTickMarks(h) {
836 dims = [
" X ",
" Y "];
838 fields = [
" Tick ",
" Scale ",
" TickLabel ",
" Data ",
" Lim ",
" TickMode "];
839 valign = [
" top ",
" middle "];
840 halign = [
" center ",
" right "];
843 for dim=1:length(dims)
844 for fidx = 1:length(
fields)
848 if strcmp(get(h,f(dim).Scale)," log ")
850 [ymin, ymax] = getLimits(h, f(dim));
852 if ~isempty(ymin) && ~isempty(ymax)
854 set(h,f(dim).TickLabel,[]);
856 ylmi = ceil(log10(ymin));
857 ylma = floor(log10(ymax));
867 step = ceil((ylma-ylmi) / 4);
870 expo = ylmi:step:ylma;
874 valid = tick >= ymin & tick <= ymax;
878 ticklbl = arrayfun(@(arg)sprintf(" \\textbf{$10^{%g}$}
",arg),expo," UniformOutput
",false);
879 colim = get(h,f(codim(dim)).Lim);
881 text(ones(size(tick))*(colim(1)-offset*(colim(2)-colim(1))),...
882 tick,ticklbl," VerticalAlignment
",valign[dim],...
883 " HorizontalAlignment
",halign[dim]," interpreter
"," LaTex
");
889 function [minlim, maxlim] = getLimits(h, f)
890 minlim = Inf; maxlim = -Inf;
891 lines = findobj(get(h," Children
")," Type
"," line
");
892 for k=1:length(lines)
893 d = get(lines(k),f.Data);
894 minlim = min(minlim, min(d(d~=0 & isfinite(d))));
895 maxlim = max(maxlim, max(d(d~=0 & isfinite(d))));
898 if lim(1) ~= 0 && isfinite(lim(1))
899 minlim = min(minlim, lim(1));
901 if lim(2) ~= 0 && isfinite(lim(2))
902 maxlim = max(maxlim, lim(2));
908 function [oldtitles , oldfonts ] = preSave(fig) {
909 allax = findobj(get(fig," Children
")," Type
"," axes
");
910 /* Get title strings */
911 oldtitles = []; /* #ok<*AGROW> */
913 childs = [" XLabel
"," YLabel
"," ZLabel
"];
914 if this.NoTitlesOnSave
915 th = get(allax," Title
");
916 if numel(th) == 1, th = [th]; end
917 oldtitles = cellfun(@(th)get(th," String
"),th,...
918 " UniformOutput
",false);
919 cellfun(@(th)set(th," String
",[]),th);
921 childs = [childs " Title
"];
924 if ~isempty(this.SaveFont)
925 for k = 1:length(allax)
927 items = [ax cell2mat(get(ax,childs)) findobj(ax," Type
"," text
")^t];
928 oldfonts[k] = get(items,fieldnames(this.SaveFont));
929 set(items,fieldnames(this.SaveFont),...
930 repmat(struct2cell(this.SaveFont)^t,numel(items),1));
936 function postSave(fig,oldtitles,oldfonts) {
937 allax = findobj(get(fig," Children
")," Type
"," axes
");
938 /* Restore title strings */
939 childs = [" XLabel
"," YLabel
"," ZLabel
"];
940 if this.NoTitlesOnSave
941 th = get(allax," Title
");
942 if numel(th) == 1, th = [th]; end
944 set(th[k]," String
",oldtitles[k]);
947 childs = [childs " Title
"];
949 if ~isempty(this.SaveFont)
950 for k = 1:length(allax)
952 items = [ax cell2mat(get(ax,childs)) findobj(ax," Type
"," text
")^t];
953 set(items,fieldnames(this.SaveFont),oldfonts[k]);
959 function saveFigure(fig,rawfilename,extlist,xargs) {
961 exts = [" fig
"," pdf
"," eps
"," jpg
"," png
"," tif
"," bmp
"];
962 /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */
963 formats = cell2mat(cellfun(@(arg)strcmp(exts,arg)^t,extlist,...
964 " UniformOutput
",false));
965 err = find(sum(formats)==0);
967 fprintf(2," Invalid extension(s): %s\n
",sprintf(" %s
",extlist[err]));
970 formats = sum(formats,2)^t;
972 if ~isempty(rawfilename) && ~isempty(extlist)
973 /* check if directory exists and resolve relative paths (export_fig subfunctions
974 * somehow tend to break) */
975 seppos = strfind(rawfilename,filesep);
976 thedir = rawfilename(1:seppos(end)-1);
977 thefile = rawfilename(seppos(end)+1:end);
978 /* Does not work if filename contains dots!
979 *[thedir, thefile] = fileparts(rawfilename); */
981 /* Special treatment for home directory, as the file name is wrapped into ""
982 * inside export_fig's commands. this prevents ~ from being resolved and thus
983 * the pdf/eps export fails. */
984 if isunix && thedir(1) == " ~
"
985 [~, homedir] = system(" echo ~
"); /* contains a linebreak, too */
987 thedir = [homedir(1:end-1) thedir(2:end)];
989 /* Fix for mangled file paths */
990 jdir = java.io.File(thedir);
991 thedir = char(jdir.getCanonicalPath);
992 file = fullfile(thedir, thefile);
993 figpos = strcmp(extlist," fig
");
994 if any(figpos) /* fig */
996 saveas(fig, [file " .fig
"], " fig
");
997 extlist(figpos) = [];
1000 extlist = cellfun(@(e)sprintf(" -%s
",e),extlist," UniformOutput
",false);
1001 args = [file, extlist[:], sprintf(" -r%d
",this.ExportDPI)];
1002 if this.ExportDPI > 100
1003 args[end+1] = " -a2
";
1005 if any(formats & logical([0 1 1 0 1 0 0])) /* pdf, eps, png */
1007 args[end+1] = " -transparent
";
1008 elseif any(formats & logical([0 1 1 1 0 0 0])) /* jpg, eps, pdf */
1010 args[end+1] = [" -q
" this.JPEGQuality];
1012 args(end+1:end+length(xargs)) = xargs;
1015 if this.WhiteBackground
1016 pos = get(fig, " Position
");
1017 oldcol = get(fig, " Color
");
1018 set(fig, " Color
", " w
", " Position
", pos);
1022 export_fig(args[:]);
1024 if this.WhiteBackground
1025 set(fig, " Color
", oldcol, " Position
", pos);
1029 fprintf(2," No file specified. Aborting\n
");
1042 public: /* ( Static ) */ /* ( Transient ) */
1044 static function pm = demo_SinglePlots() {
1047 pm.FilePrefix= " my_pm_single
";
1049 /* Here: Run your matlab script/code, do computations, etc
1050 * At some stage: Plotting is needed. Now call your plotting function/script with
1051 * the PlotManager argument. The big advantage of this is, that you can call your
1052 * plotting method with whatever setting to the PlotManager, so one time you have it
1053 * plotting to subplots (=development time) and the next you create single plots
1054 * with specific export settings (=publication/report time) */
1056 /* Inside your plotting method, create new axes using the nextPlot command. */
1058 h = pm.nextPlot(" plot1
"," Title of plot 1, look it has axes labels
"," xlabel
"," ylabel
");
1059 /* [.. do whatever plotting here using the axes handle h] */
1060 PlotManager.doPlot(h);
1062 h = pm.nextPlot(" plot2
"," Only title given
");
1063 /* [.. do whatever plotting here using the axes handle h] */
1064 PlotManager.doPlot(h);
1066 /* Finish off the current plot, which will add labels etc to it. */
1078 static function pm = demo_Subplots() {
1079 pm = PlotManager(false,2,2);
1081 pm.FilePrefix= " my_pm_subplots
";
1082 /* [.. your plot function called with argument pm ..] */
1083 h = pm.nextPlot(" tag_of_subplot1
"," Title of subplot 1
"," xlabel
"," ylabel
");
1084 PlotManager.doPlot(h);
1085 h = pm.nextPlot(" tag_of_subplot2
"," Only title given
");
1086 PlotManager.doPlot(h);
1087 h = pm.nextPlot(" tag_of_subplot3
"," title of subplot 3, no y label
"," xlabel
",[],[" legend!
"]);
1088 PlotManager.doPlot(h);
1093 static function pm = demo_SavePlots() {
1094 pm = PlotManager.demo_SinglePlots;
1095 pm.SaveFormats= [" jpg
"," png
"];
1096 pm.UseFileTypeFolders= false;
1098 pm.FilePrefix= " sameplots_withseparate_dir
";
1099 pm.UseFileTypeFolders= true;
1100 /* Disable saving of titles! */
1101 pm.NoTitlesOnSave= true;
1102 pm.savePlots(pwd," Close
",true);
1106 static function pm = demo_SavePlots_Details() {
1107 pm = PlotManager.demo_SinglePlots;
1108 pm.UseFileTypeFolders= false;
1109 /* Add extra legend plot */
1110 h = pm.nextPlot(" withlegend
"," Some plot with a legend!
"," x
"," y
",[" line 1
", " line 2
", " line 3
"]);
1112 plot(h,x,[cos(x).*sin(x); cos(x); cosh(x)]);
1114 /* Save with specific format and separate legend */
1115 pm.savePlots(pwd," Format
",[" png
"]," SeparateLegends
",[false false true]);
1117 /* Save under different file type, only a couple, and close ONLY THEM afterwards. */
1118 pm.savePlots(pwd," Format
",[" jpg
"]," Selection
",[1 3]," Close
",true);
1129 static function pm = demo_Zoom() {
1130 pm = PlotManager.demo_SinglePlots;
1131 /* Add extra legend plot */
1132 h = pm.nextPlot(" withlegend
"," Some plot with a legend!
"," x
"," y
",[" line 1
", " line 2
", " line 3
"]);
1134 plot(h,x,[cos(x).*sin(x); cos(x); tanh(x)]);
1135 /* The latest figure number is three (so far got to know which is which) */
1136 pm.createZoom(3, [5 10], " zoom
");
1137 pm.createZoom(3, [-3 2], " zoom_nolegend
", false);
1142 private: /* ( Static ) */ /* ( Transient ) */
1144 static function doPlot(h) {
1145 r = RandStream(" mt19937ar
"," Seed
",round(cputime*1000));
1147 x = linspace(-r.rand*5,r.rand*5,100);
1149 f = @(x,y)sin(y.*x/(3*r.rand*pi));
1151 f = @(x,y)log10(2*cosh(abs(x-y)).^(sin(x/r.rand*3)));
1153 f = @(x,y)[r.rand*cos(x).*sin(y); pi*sin(x)];
1155 if fr < .6 && r.rand < .5
1156 [X,Y] = meshgrid(x);
1157 surf(h,X,Y,f(X,Y)," EdgeColor
"," None
");
1159 plot(h,x,f(x,x.^2));
logical NoTitlesOnSave
Flag that determines if any figures title's are removed when using savePlots.
function resetCount()
Resets the current axes handle count so that subsequent calls to "nextPlot" will result re-returnin...
integer ExportDPI
DPI used for export. See export_fig settings.
fields
Returns a cell array of string containing the names of public properties.
function savePlots(char folder, varargin)
Saves all plots that have been created thus far to a given folder with given format.
rowvec< double > FigureSize
The figure size for each newly created figure. Set to [] to use system default.
logical DoubleSaveJPG
For some reason on unix machines export_fig sometimes uses the last image saved to as the next one...
reshape
hanges the dimensions of the handle object array to the specified dimensions. See the MATLAB reshape ...
function h = copyFigure(nr, newtag)
Copies the plot with the given number and returns the handle to its axis.
PlotManager: Small class that allows the same plots generated by some script to be either organized a...
Matlab's base handle class (documentation generation substitute)
logical UseFileTypeFolders
Affects the savePlots behaviour. This flag lets the PlotManager create subfolders in the target folde...
function done()
Finishes the current plotting process.
logical LeaveOpen
Flag indicating if the plots should be left open once the PlotManager is deleted (as variable) ...
A variable number of input arguments.
function h = createZoom(nr, area, tagextra, withlegend)
function axes ax_handle = nextPlot(char tag,char caption,char xlab,char ylab,cell< char > leg_str,integer numsubplots)
Creates a new axis to plot in. Depending on the property tools.PlotMananger.Single this will either a...
logical Single
Flag if single plots shall be used for subsequent calls to nextPlot.
logical WhiteBackground
Flag that determines if a white 'figure' background should be used instead of any set or default (gre...
function closeAll(selection)
Closes all currently openend plots and resets the Handles property.
integer MaxFigures
Controls the maximum number of simultaneously opened figures.
rowvec< integer > AutoTickMarks
An integer number to enforce a minimum number of tickmarks on the respective axes.
findobj
Finds objects matching the specified conditions from the input array of handle objects.
function res = isposintscalar(value)
isposintscalar: Backwards-compatibility function for matlab versions greater than 2012a ...
cell< char > SaveFormats
The image formats to use when savePlots is called.
PlotManager(logical single,integer rows,integer cols)
Creates a new PlotManager.
char FilePrefix
A prefix that has to be put before each file name for exported plots.
char JPEGQuality
JPEG quality used for export. See export_fig settings.
A MatLab character array.
rowvec< double > Figures
Provides access to all figure handles created using nextPlot.
function setFigureNames(name)
function matchPlotAxes(ax_handles, varargin)