function varargout = exportfig(varargin)
%EXPORTFIG Export a figure.
% EXPORTFIG(H, FILENAME) writes the figure H to FILENAME. H is
% a figure handle and FILENAME is a string that specifies the
% name of the output file.
%
% EXPORTFIG(H, FILENAME, OPTIONS) writes the figure H to FILENAME
% with options initially specified by the structure OPTIONS. The
% field names of OPTIONS must be legal parameters listed below
% and the field values must be legal values for the corresponding
% parameter. Default options can be set in releases prior to R12
% by storing the OPTIONS structure in the root object's appdata
% with the command
% setappdata(0,'exportfigdefaults', OPTIONS)
% and for releases after R12 by setting the preference with the
% command
% setpref('exportfig', 'defaults', OPTIONS)
%
% EXPORTFIG(...,PARAM1,VAL1,PARAM2,VAL2,...) specifies
% parameters that control various characteristics of the output
% file. Any parameter value can be the string 'auto' which means
% the parameter uses the default factory behavior, overriding
% any other default for the parameter.
%
% Format Paramter:
% 'Format' a string
% specifies the output format. Defaults to 'eps'. For a
% list of export formats type 'help print'.
% 'Preview' one of the strings 'none', 'tiff'
% specifies a preview for EPS files. Defaults to 'none'.
%
% Size Parameters:
% 'Width' a positive scalar
% specifies the width in the figure's PaperUnits
% 'Height' a positive scalar
% specifies the height in the figure's PaperUnits
% 'Bounds' one of the strings 'tight', 'loose'
% specifies a tight or loose bounding box. Defaults to 'tight'.
% 'BoundsCode' one of the strings 'internal', 'mcode'
% specifies whether to use the internal EPS code or
% general m-code for computing bounding boxes. Defaults to
% 'internal'.
% 'Reference' an axes handle or a string
% specifies that the width and height parameters
% are relative to the given axes. If a string is
% specified then it must evaluate to an axes handle.
%
% Specifying only one dimension sets the other dimension
% so that the exported aspect ratio is the same as the
% figure's or reference axes' current aspect ratio.
% If neither dimension is specified the size defaults to
% the width and height from the figure's or reference
% axes' size. Tight bounding boxes are only computed for
% 2-D views and in that case the computed bounds enclose all
% text objects.
%
% Rendering Parameters:
% 'Color' one of the strings 'bw', 'gray', 'cmyk'
% 'bw' specifies that lines and text are exported in
% black and all other objects in grayscale
% 'gray' specifies that all objects are exported in grayscale
% 'rgb' specifies that all objects are exported in color
% using the RGB color space
% 'cmyk' specifies that all objects are exported in color
% using the CMYK color space
% 'Renderer' one of 'painters', 'zbuffer', 'opengl'
% specifies the renderer to use
% 'Resolution' a positive scalar
% specifies the resolution in dots-per-inch.
% 'LockAxes' one of 0 or 1
% specifies that all axes limits and ticks should be fixed
% while exporting.
%
% The default color setting is 'bw'.
%
% Font Parameters:
% 'FontMode' one of the strings 'scaled', 'fixed'
% 'FontSize' a positive scalar
% in 'scaled' mode multiplies with the font size of each
% text object to obtain the exported font size
% in 'fixed' mode specifies the font size of all text
% objects in points
% 'DefaultFixedFontSize' a positive scalar
% in 'fixed' mode specified the default font size in
% points
% 'FontSizeMin' a positive scalar
% specifies the minimum font size allowed after scaling
% 'FontSizeMax' a positive scalar
% specifies the maximum font size allowed after scaling
% 'FontEncoding' one of the strings 'latin1', 'adobe'
% specifies the character encoding of the font
% 'SeparateText' one of 0 or 1
% specifies that the text objects are stored in separate
% file as EPS with the base filename having '_t' appended.
%
% If FontMode is 'scaled' but FontSize is not specified then a
% scaling factor is computed from the ratio of the size of the
% exported figure to the size of the actual figure.
%
% The default 'FontMode' setting is 'scaled'.
%
% Line Width Parameters:
% 'LineMode' one of the strings 'scaled', 'fixed'
% 'LineWidth' a positive scalar
% 'DefaultFixedLineWidth' a positive scalar
% 'LineWidthMin' a positive scalar
% specifies the minimum line width allowed after scaling
% 'LineWidthMax' a positive scalar
% specifies the maximum line width allowed after scaling
% The semantics of 'Line' parameters are exactly the
% same as the corresponding 'Font' parameters, except that
% they apply to line widths instead of font sizes.
%
% Style Map Parameter:
% 'LineStyleMap' one of [], 'bw', or a function name or handle
% specifies how to map line colors to styles. An empty
% style map means styles are not changed. The style map
% 'bw' is a built-in mapping that maps lines with the same
% color to the same style and otherwise cycles through the
% available styles. A user-specified map is a function
% that takes as input a cell array of line objects and
% outputs a cell array of line style strings. The default
% map is [].
%
% Examples:
% exportfig(gcf,'fig1.eps','height',3);
% Exports the current figure to the file named 'fig1.eps' with
% a height of 3 inches (assuming the figure's PaperUnits is
% inches) and an aspect ratio the same as the figure's aspect
% ratio on screen.
%
% opts = struct('FontMode','fixed','FontSize',10,'height',3);
% exportfig(gcf, 'fig2.eps', opts, 'height', 5);
% Exports the current figure to 'fig2.eps' with all
% text in 10 point fonts and with height 5 inches.
%
% See also PREVIEWFIG, APPLYTOFIG, RESTOREFIG, PRINT.
% Copyright 2000 Ben Hinkle
% Email bug reports and comments to bhinkle@mathworks.com
if (nargin < 2)
error('Too few input arguments');
end
% exportfig(H, filename, [options,] ...)
H = varargin{1};
if ~LocalIsHG(H,'figure')
error('First argument must be a handle to a figure.');
end
filename = varargin{2};
if ~ischar(filename)
error('Second argument must be a string.');
end
paramPairs = {varargin{3:end}};
if nargin > 2
if isstruct(paramPairs{1})
pcell = LocalToCell(paramPairs{1});
paramPairs = {pcell{:}, paramPairs{2:end}};
end
end
verstr = version;
majorver = str2num(verstr(1));
defaults = [];
if majorver > 5
if ispref('exportfig','defaults')
defaults = getpref('exportfig','defaults');
end
elseif exist('getappdata')
defaults = getappdata(0,'exportfigdefaults');
end
if ~isempty(defaults)
dcell = LocalToCell(defaults);
paramPairs = {dcell{:}, paramPairs{:}};
end
% Do some validity checking on param-value pairs
if (rem(length(paramPairs),2) ~= 0)
error(['Invalid input syntax. Optional parameters and values' ...
' must be in pairs.']);
end
auto.format = 'eps';
auto.preview = 'none';
auto.width = -1;
auto.height = -1;
auto.color = 'bw';
auto.defaultfontsize=10;
auto.fontsize = -1;
auto.fontmode='scaled';
auto.fontmin = 8;
auto.fontmax = 60;
auto.defaultlinewidth = 1.0;
auto.linewidth = -1;
auto.linemode=[];
auto.linemin = 0.5;
auto.linemax = 100;
auto.fontencoding = 'latin1';
auto.renderer = [];
auto.resolution = [];
auto.stylemap = [];
auto.applystyle = 0;
auto.refobj = -1;
auto.bounds = 'tight';
auto.boundscode = 'internal';
explicitbounds = 0;
auto.lockaxes = 1;
auto.separatetext = 0;
opts = auto;
% Process param-value pairs
args = {};
for k = 1:2:length(paramPairs)
param = lower(paramPairs{k});
if ~ischar(param)
error('Optional parameter names must be strings');
end
value = paramPairs{k+1};
switch (param)
case 'format'
opts.format = LocalCheckAuto(lower(value),auto.format);
if strcmp(opts.format,'preview')
error(['Format ''preview'' no longer supported. Use PREVIEWFIG' ...
' instead.']);
end
case 'preview'
opts.preview = LocalCheckAuto(lower(value),auto.preview);
if ~strcmp(opts.preview,{'none','tiff'})
error('Preview must be ''none'' or ''tiff''.');
end
case 'width'
opts.width = LocalToNum(value, auto.width);
if ~ischar(value) | ~strcmp(value,'auto')
if ~LocalIsPositiveScalar(opts.width)
error('Width must be a numeric scalar > 0');
end
end
case 'height'
opts.height = LocalToNum(value, auto.height);
if ~ischar(value) | ~strcmp(value,'auto')
if(~LocalIsPositiveScalar(opts.height))
error('Height must be a numeric scalar > 0');
end
end
case 'color'
opts.color = LocalCheckAuto(lower(value),auto.color);
if ~strcmp(opts.color,{'bw','gray','rgb','cmyk'})
error('Color must be ''bw'', ''gray'',''rgb'' or ''cmyk''.');
end
case 'fontmode'
opts.fontmode = LocalCheckAuto(lower(value),auto.fontmode);
if ~strcmp(opts.fontmode,{'scaled','fixed'})
error('FontMode must be ''scaled'' or ''fixed''.');
end
case 'fontsize'
opts.fontsize = LocalToNum(value,auto.fontsize);
if ~ischar(value) | ~strcmp(value,'auto')
if ~LocalIsPositiveScalar(opts.fontsize)
error('FontSize must be a numeric scalar > 0');
end
end
case 'defaultfixedfontsize'
opts.defaultfontsize = LocalToNum(value,auto.defaultfontsize);
if ~ischar(value) | ~strcmp(value,'auto')
if ~LocalIsPositiveScalar(opts.defaultfontsize)
error('DefaultFixedFontSize must be a numeric scalar > 0');
end
end
case 'fontsizemin'
opts.fontmin = LocalToNum(value,auto.fontmin);
if ~ischar(value) | ~strcmp(value,'auto')
if ~LocalIsPositiveScalar(opts.fontmin)
error('FontSizeMin must be a numeric scalar > 0');
end
end
case 'fontsizemax'
opts.fontmax = LocalToNum(value,auto.fontmax);
if ~ischar(value) | ~strcmp(value,'auto')
if ~LocalIsPositiveScalar(opts.fontmax)
error('FontSizeMax must be a numeric scalar > 0');
end
end
case 'fontencoding'
opts.fontencoding = LocalCheckAuto(lower(value),auto.fontencoding);
if ~strcmp(opts.fontencoding,{'latin1','adobe'})
error('FontEncoding must be ''latin1'' or ''adobe''.');
end
case 'linemode'
opts.linemode = LocalCheckAuto(lower(value),auto.linemode);
if ~strcmp(opts.linemode,{'scaled','fixed'})
error('LineMode must be ''scaled'' or ''fixed''.');
end
case 'linewidth'
opts.linewidth = LocalToNum(value,auto.linewidth);
if ~ischar(value) | ~strcmp(value,'auto')
if ~LocalIsPositiveScalar(opts.linewidth)
error('LineWidth must be a numeric scalar > 0');
end
end
case 'defaultfixedlinewidth'
opts.defaultlinewidth = LocalToNum(value,auto.defaultlinewidth);
if ~ischar(value) | ~strcmp(value,'auto')
if ~LocalIsPositiveScalar(opts.defaultlinewidth)
error(['DefaultFixedLineWidth must be a numeric scalar >' ...
' 0']);
end
end
case 'linewidthmin'
opts.linemin = LocalToNum(value,auto.linemin);
if ~ischar(value) | ~strcmp(value,'auto')
if ~LocalIsPositiveScalar(opts.linemin)
error('LineWidthMin must be a numeric scalar > 0');
end
end
case 'linewidthmax'
opts.linemax = LocalToNum(value,auto.linemax);
if ~ischar(value) | ~strcmp(value,'auto')
if ~LocalIsPositiveScalar(opts.linemax)
error('LineWidthMax must be a numeric scalar > 0');
end
end
case 'linestylemap'
opts.stylemap = LocalCheckAuto(value,auto.stylemap);
case 'renderer'
opts.renderer = LocalCheckAuto(lower(value),auto.renderer);
if ~ischar(value) | ~strcmp(value,'auto')
if ~strcmp(opts.renderer,{'painters','zbuffer','opengl'})
error(['Renderer must be ''painters'', ''zbuffer'' or' ...
' ''opengl''.']);
end
end
case 'resolution'
opts.resolution = LocalToNum(value,auto.resolution);
if ~ischar(value) | ~strcmp(value,'auto')
if ~(isnumeric(value) & (prod(size(value)) == 1) & (value >= 0));
error('Resolution must be a numeric scalar >= 0');
end
end
case 'applystyle' % means to apply the options and not export
opts.applystyle = 1;
case 'reference'
if ischar(value)
if strcmp(value,'auto')
opts.refobj = auto.refobj;
else
opts.refobj = eval(value);
end
else
opts.refobj = value;
end
if ~LocalIsHG(opts.refobj,'axes')
error('Reference object must evaluate to an axes handle.');
end
case 'bounds'
opts.bounds = LocalCheckAuto(lower(value),auto.bounds);
explicitbounds = 1;
if ~strcmp(opts.bounds,{'tight','loose'})
error('Bounds must be ''tight'' or ''loose''.');
end
case 'boundscode'
opts.boundscode = LocalCheckAuto(lower(value),auto.boundscode);
if ~strcmp(opts.boundscode,{'internal','mcode'})
error('BoundsCode must be ''internal'' or ''mcode''.');
end
case 'lockaxes'
opts.lockaxes = LocalToNum(value,auto.lockaxes);
case 'separatetext'
opts.separatetext = LocalToNum(value,auto.separatetext);
otherwise
error(['Unrecognized option ' param '.']);
end
end
% make sure figure is up-to-date
drawnow;
allLines = findall(H, 'type', 'line');
allText = findall(H, 'type', 'text');
allAxes = findall(H, 'type', 'axes');
allImages = findall(H, 'type', 'image');
allLights = findall(H, 'type', 'light');
allPatch = findall(H, 'type', 'patch');
allSurf = findall(H, 'type', 'surface');
allRect = findall(H, 'type', 'rectangle');
allFont = [allText; allAxes];
allColor = [allLines; allText; allAxes; allLights];
allMarker = [allLines; allPatch; allSurf];
allEdge = [allPatch; allSurf];
allCData = [allImages; allSurf];
% need to explicitly get ticks for some invisible figures
get(allAxes,'yticklabel');
old.objs = {};
old.prop = {};
old.values = {};
% Process format
if strncmp(opts.format,'eps',3) & ~strcmp(opts.preview,'none')
args = {args{:}, ['-' opts.preview]};
end
hadError = 0;
oldwarn = warning;
try
% lock axes limits, ticks and labels if requested
if opts.lockaxes
old = LocalManualAxesMode(old, allAxes, 'TickMode');
old = LocalManualAxesMode(old, allAxes, 'TickLabelMode');
old = LocalManualAxesMode(old, allAxes, 'LimMode');
end
% Process size parameters
figurePaperUnits = get(H, 'PaperUnits');
oldFigureUnits = get(H, 'Units');
oldFigPos = get(H,'Position');
set(H, 'Units', figurePaperUnits);
figPos = get(H,'Position');
refsize = figPos(3:4);
if opts.refobj ~= -1
oldUnits = get(opts.refobj, 'Units');
set(opts.refobj, 'Units', figurePaperUnits);
r = get(opts.refobj, 'Position');
refsize = r(3:4);
set(opts.refobj, 'Units', oldUnits);
end
aspectRatio = refsize(1)/refsize(2);
if (opts.width == -1) & (opts.height == -1)
opts.width = refsize(1);
opts.height = refsize(2);
elseif (opts.width == -1)
opts.width = opts.height * aspectRatio;
elseif (opts.height == -1)
opts.height = opts.width / aspectRatio;
end
wscale = opts.width/refsize(1);
hscale = opts.height/refsize(2);
sizescale = min(wscale,hscale);
old = LocalPushOldData(old,H,'PaperPositionMode', ...
get(H,'PaperPositionMode'));
set(H, 'PaperPositionMode', 'auto');
newPos = [figPos(1) figPos(2)+figPos(4)*(1-hscale) ...
wscale*figPos(3) hscale*figPos(4)];
set(H, 'Position', newPos);
set(H, 'Units', oldFigureUnits);
old = LocalPushOldData(old,H,'Color', ...
get(H,'Color'));
set(H,'Color','w');
% process line-style map
if ~isempty(opts.stylemap) & ~isempty(allLines)
oldlstyle = LocalGetAsCell(allLines,'LineStyle');
old = LocalPushOldData(old, allLines, {'LineStyle'}, ...
oldlstyle);
newlstyle = oldlstyle;
if ischar(opts.stylemap) & strcmpi(opts.stylemap,'bw')
newlstyle = LocalMapColorToStyle(allLines);
else
try
newlstyle = feval(opts.stylemap,allLines);
catch
warning(['Skipping stylemap. ' lasterr]);
end
end
set(allLines,{'LineStyle'},newlstyle);
end
% Process rendering parameters
switch (opts.color)
case {'bw', 'gray'}
if ~strcmp(opts.color,'bw') & strncmp(opts.format,'eps',3)
opts.format = [opts.format 'c'];
end
args = {args{:}, ['-d' opts.format]};
%compute and set gray colormap
oldcmap = get(H,'Colormap');
newgrays = 0.30*oldcmap(:,1) + 0.59*oldcmap(:,2) + 0.11*oldcmap(:,3);
newcmap = [newgrays newgrays newgrays];
old = LocalPushOldData(old, H, 'Colormap', oldcmap);
set(H, 'Colormap', newcmap);
%compute and set ColorSpec and CData properties
old = LocalUpdateColors(allColor, 'color', old);
old = LocalUpdateColors(allAxes, 'xcolor', old);
old = LocalUpdateColors(allAxes, 'ycolor', old);
old = LocalUpdateColors(allAxes, 'zcolor', old);
old = LocalUpdateColors(allMarker, 'MarkerEdgeColor', old);
old = LocalUpdateColors(allMarker, 'MarkerFaceColor', old);
old = LocalUpdateColors(allEdge, 'EdgeColor', old);
old = LocalUpdateColors(allEdge, 'FaceColor', old);
old = LocalUpdateColors(allCData, 'CData', old);
if strcmp(opts.color,'bw')
lcolor = LocalGetAsCell(allLines,'color');
n = length(lcolor);
for k=1:n
if (lcolor{k}(1) < 1-eps)
set(allLines(k),'color','k');
end
end
end
case {'rgb','cmyk'}
if strncmp(opts.format,'eps',3)
opts.format = [opts.format 'c'];
args = {args{:}, ['-d' opts.format]};
if strcmp(opts.color,'cmyk')
args = {args{:}, '-cmyk'};
end
else
args = {args{:}, ['-d' opts.format]};
end
otherwise
error('Invalid Color parameter');
end
if (~isempty(opts.renderer))
args = {args{:}, ['-' opts.renderer]};
end
if (~isempty(opts.resolution)) | ~strncmp(opts.format,'eps',3)
if isempty(opts.resolution)
opts.resolution = 0;
end
args = {args{:}, ['-r' int2str(opts.resolution)]};
end
% Process font parameters
if ~isempty(opts.fontmode)
oldfonts = LocalGetAsCell(allFont,'FontSize');
oldfontunits = LocalGetAsCell(allFont,'FontUnits');
set(allFont,'FontUnits','points');
switch (opts.fontmode)
case 'fixed'
if (opts.fontsize == -1)
set(allFont,'FontSize',opts.defaultfontsize);
else
set(allFont,'FontSize',opts.fontsize);
end
case 'scaled'
if (opts.fontsize == -1)
scale = sizescale;
else
scale = opts.fontsize;
end
newfonts = LocalScale(oldfonts,scale,opts.fontmin,opts.fontmax);
set(allFont,{'FontSize'},newfonts);
otherwise
error('Invalid FontMode parameter');
end
old = LocalPushOldData(old, allFont, {'FontSize'}, oldfonts);
old = LocalPushOldData(old, allFont, {'FontUnits'}, oldfontunits);
end
if strcmp(opts.fontencoding,'adobe') & strncmp(opts.format,'eps',3)
args = {args{:}, '-adobecset'};
end
% Process line parameters
if ~isempty(opts.linemode)
oldlines = LocalGetAsCell(allMarker,'LineWidth');
old = LocalPushOldData(old, allMarker, {'LineWidth'}, oldlines);
switch (opts.linemode)
case 'fixed'
if (opts.linewidth == -1)
set(allMarker,'LineWidth',opts.defaultlinewidth);
else
set(allMarker,'LineWidth',opts.linewidth);
end
case 'scaled'
if (opts.linewidth == -1)
scale = sizescale;
else
scale = opts.linewidth;
end
newlines = LocalScale(oldlines, scale, opts.linemin, opts.linemax);
set(allMarker,{'LineWidth'},newlines);
end
end
% adjust figure bounds to surround axes
if strcmp(opts.bounds,'tight')
if (~strncmp(opts.format,'eps',3) & LocalHas3DPlot(allAxes)) | ...
(strncmp(opts.format,'eps',3) & opts.separatetext)
if (explicitbounds == 1)
warning(['Cannot compute ''tight'' bounds. Using ''loose''' ...
' bounds.']);
end
opts.bounds = 'loose';
end
end
warning('off');
if ~isempty(allAxes)
usemcode = 1;
if strncmp(opts.format,'eps',3)
if strcmp(opts.boundscode,'internal')
if strcmp(opts.bounds,'loose')
args = {args{:}, '-loose'};
end
old = LocalPushOldData(old,H,'Position', oldFigPos);
usemcode = 0;
else
usemcode = 1;
end
end
if strcmp(opts.bounds,'tight') & usemcode
oldaunits = LocalGetAsCell(allAxes,'Units');
oldapos = LocalGetAsCell(allAxes,'Position');
oldtunits = LocalGetAsCell(allText,'units');
oldtpos = LocalGetAsCell(allText,'Position');
set(allAxes,'units','points');
apos = LocalGetAsCell(allAxes,'Position');
oldunits = get(H,'Units');
set(H,'units','points');
origfr = get(H,'position');
fr = [];
for k=1:length(allAxes)
if ~strcmpi(get(allAxes(k),'Tag'),'legend')
axesR = apos{k};
r = LocalAxesTightBoundingBox(axesR, allAxes(k));
if ~isempty(r)
r(1:2) = r(1:2) + axesR(1:2);
fr = LocalUnionRect(fr,r);
end
end
end
if isempty(fr)
fr = [0 0 origfr(3:4)];
end
for k=1:length(allAxes)
ax = allAxes(k);
r = apos{k};
r(1:2) = r(1:2) - fr(1:2);
set(ax,'Position',r);
end
old = LocalPushOldData(old, allAxes, {'Position'}, oldapos);
old = LocalPushOldData(old, allText, {'Position'}, oldtpos);
old = LocalPushOldData(old, allText, {'Units'}, oldtunits);
old = LocalPushOldData(old, allAxes, {'Units'}, oldaunits);
old = LocalPushOldData(old, H, 'Position', oldFigPos);
old = LocalPushOldData(old, H, 'Units', oldFigureUnits);
r = [origfr(1) origfr(2)+origfr(4)-fr(4) fr(3:4)];
set(H,'Position',r);
end
end
% Process text in a separate file if needed
if opts.separatetext & ~opts.applystyle
% First hide all text and export
oldtvis = LocalGetAsCell(allText,'visible');
set(allText,'visible','off');
oldax = LocalGetAsCell(allAxes,'XTickLabel',1);
olday = LocalGetAsCell(allAxes,'YTickLabel',1);
oldaz = LocalGetAsCell(allAxes,'ZTickLabel',1);
null = cell(length(oldax),1);
[null{:}] = deal([]);
set(allAxes,{'XTickLabel'},null);
set(allAxes,{'YTickLabel'},null);
set(allAxes,{'ZTickLabel'},null);
print(H, filename, args{:});
set(allText,{'Visible'},oldtvis);
set(allAxes,{'XTickLabel'},oldax);
set(allAxes,{'YTickLabel'},olday);
set(allAxes,{'ZTickLabel'},oldaz);
% Now hide all non-text and export as eps in painters
[path, name, ext] = fileparts(filename);
tfile = fullfile(path,[name '_t.eps']);
tfile2 = fullfile(path,[name '_t2.eps']);
foundRenderer = 0;
for k=1:length(args)
if strncmp('-d',args{k},2)
args{k} = '-deps';
elseif strncmp('-zbuffer',args{k},8) | ...
strncmp('-opengl', args{k},6)
args{k} = '-painters';
foundRenderer = 1;
end
end
if ~foundRenderer
args = {args{:}, '-painters'};
end
allNonText = [allLines; allLights; allPatch; ...
allImages; allSurf; allRect];
oldvis = LocalGetAsCell(allNonText,'visible');
oldc = LocalGetAsCell(allAxes,'color');
oldaxg = LocalGetAsCell(allAxes,'XGrid');
oldayg = LocalGetAsCell(allAxes,'YGrid');
oldazg = LocalGetAsCell(allAxes,'ZGrid');
[null{:}] = deal('off');
set(allAxes,{'XGrid'},null);
set(allAxes,{'YGrid'},null);
set(allAxes,{'ZGrid'},null);
set(allNonText,'Visible','off');
set(allAxes,'Color','none');
print(H, tfile2, args{:});
set(allNonText,{'Visible'},oldvis);
set(allAxes,{'Color'},oldc);
set(allAxes,{'XGrid'},oldaxg);
set(allAxes,{'YGrid'},oldayg);
set(allAxes,{'ZGrid'},oldazg);
%hack up the postscript file
fid1 = fopen(tfile,'w');
fid2 = fopen(tfile2,'r');
line = fgetl(fid2);
while ischar(line)
if strncmp(line,'%%Title',7)
fprintf(fid1,'%s\n',['%%Title: ', tfile]);
elseif (length(line) < 3)
fprintf(fid1,'%s\n',line);
elseif ~strcmp(line(end-2:end),' PR') & ...
~strcmp(line(end-1:end),' L')
fprintf(fid1,'%s\n',line);
end
line = fgetl(fid2);
end
fclose(fid1);
fclose(fid2);
delete(tfile2);
elseif ~opts.applystyle
drawnow;
print(H, filename, args{:});
end
warning(oldwarn);
catch
warning(oldwarn);
hadError = 1;
end
% Restore figure settings
if opts.applystyle
varargout{1} = old;
else
for n=1:length(old.objs)
if ~iscell(old.values{n}) & iscell(old.prop{n})
old.values{n} = {old.values{n}};
end
set(old.objs{n}, old.prop{n}, old.values{n});
end
end
if hadError
error(deblank(lasterr));
end
%
% Local Functions
%
function outData = LocalPushOldData(inData, objs, prop, values)
outData.objs = {objs, inData.objs{:}};
outData.prop = {prop, inData.prop{:}};
outData.values = {values, inData.values{:}};
function cellArray = LocalGetAsCell(fig,prop,allowemptycell);
cellArray = get(fig,prop);
if nargin < 3
allowemptycell = 0;
end
if ~iscell(cellArray) & (allowemptycell | ~isempty(cellArray))
cellArray = {cellArray};
end
function newArray = LocalScale(inArray, scale, minv, maxv)
n = length(inArray);
newArray = cell(n,1);
for k=1:n
newArray{k} = min(maxv,max(minv,scale*inArray{k}(1)));
end
function gray = LocalMapToGray1(color)
gray = color;
if ischar(color)
switch color(1)
case 'y'
color = [1 1 0];
case 'm'
color = [1 0 1];
case 'c'
color = [0 1 1];
case 'r'
color = [1 0 0];
case 'g'
color = [0 1 0];
case 'b'
color = [0 0 1];
case 'w'
color = [1 1 1];
case 'k'
color = [0 0 0];
end
end
if ~ischar(color)
gray = 0.30*color(1) + 0.59*color(2) + 0.11*color(3);
end
function newArray = LocalMapToGray(inArray);
n = length(inArray);
newArray = cell(n,1);
for k=1:n
color = inArray{k};
if ~isempty(color)
color = LocalMapToGray1(color);
end
if isempty(color) | ischar(color)
newArray{k} = color;
else
newArray{k} = [color color color];
end
end
function newArray = LocalMapColorToStyle(inArray);
inArray = LocalGetAsCell(inArray,'Color');
n = length(inArray);
newArray = cell(n,1);
styles = {'-','--',':','-.'};
uniques = [];
nstyles = length(styles);
for k=1:n
gray = LocalMapToGray1(inArray{k});
if isempty(gray) | ischar(gray) | gray < .05
newArray{k} = '-';
else
if ~isempty(uniques) & any(gray == uniques)
ind = find(gray==uniques);
else
uniques = [uniques gray];
ind = length(uniques);
end
newArray{k} = styles{mod(ind-1,nstyles)+1};
end
end
function newArray = LocalMapCData(inArray);
n = length(inArray);
newArray = cell(n,1);
for k=1:n
color = inArray{k};
if (ndims(color) == 3) & isa(color,'double')
gray = 0.30*color(:,:,1) + 0.59*color(:,:,2) + 0.11*color(:,:,3);
color(:,:,1) = gray;
color(:,:,2) = gray;
color(:,:,3) = gray;
end
newArray{k} = color;
end
function outData = LocalUpdateColors(inArray, prop, inData)
value = LocalGetAsCell(inArray,prop);
outData.objs = {inData.objs{:}, inArray};
outData.prop = {inData.prop{:}, {prop}};
outData.values = {inData.values{:}, value};
if (~isempty(value))
if strcmp(prop,'CData')
value = LocalMapCData(value);
else
value = LocalMapToGray(value);
end
set(inArray,{prop},value);
end
function bool = LocalIsPositiveScalar(value)
bool = isnumeric(value) & ...
prod(size(value)) == 1 & ...
value > 0;
function value = LocalToNum(value,auto)
if ischar(value)
if strcmp(value,'auto')
value = auto;
else
value = str2num(value);
end
end
%convert a struct to {field1,val1,field2,val2,...}
function c = LocalToCell(s)
f = fieldnames(s);
v = struct2cell(s);
opts = cell(2,length(f));
opts(1,:) = f;
opts(2,:) = v;
c = {opts{:}};
function c = LocalIsHG(obj,hgtype)
c = 0;
if (length(obj) == 1) & ishandle(obj)
c = strcmp(get(obj,'type'),hgtype);
end
function c = LocalHas3DPlot(a)
zticks = LocalGetAsCell(a,'ZTickLabel');
c = 0;
for k=1:length(zticks)
if ~isempty(zticks{k})
c = 1;
return;
end
end
function r = LocalUnionRect(r1,r2)
if isempty(r1)
r = r2;
elseif isempty(r2)
r = r1;
elseif max(r2(3:4)) > 0
left = min(r1(1),r2(1));
bot = min(r1(2),r2(2));
right = max(r1(1)+r1(3),r2(1)+r2(3));
top = max(r1(2)+r1(4),r2(2)+r2(4));
r = [left bot right-left top-bot];
else
r = r1;
end
function r = LocalAxesTightBoundingBox(axesR, a)
if strcmp(get(a,'handlevisibility'),'on')
r = get(a,'position');
else
r = [];
end
atext = findall(a,'type','text','visible','on');
if ~isempty(atext)
set(atext,'units','points');
res=LocalGetAsCell(atext,'extent');
for n=1:length(atext)
r = LocalUnionRect(r,res{n});
end
end
if strcmp(get(a,'visible'),'on')
r = LocalUnionRect(r,[0 0 axesR(3:4)]);
oldunits = get(a,'fontunits');
set(a,'fontunits','points');
label = text(0,0,'','parent',a,...
'units','points',...
'fontsize',get(a,'fontsize'),...
'fontname',get(a,'fontname'),...
'fontweight',get(a,'fontweight'),...
'fontangle',get(a,'fontangle'),...
'visible','off');
fs = get(a,'fontsize');
% handle y axis tick labels
ry = [0 0 0 axesR(4)];
ylabs = get(a,'yticklabels');
yticks = get(a,'ytick');
maxw = 0;
if ~isempty(ylabs)
for n=1:size(ylabs,1)
if strcmp(get(a,'yscale'),'log')
set(label,'string',['10^' ylabs(n,:)]);
else
set(label,'string',ylabs(n,:));
end
ext = get(label,'extent');
maxw = max(maxw,ext(3));
end
if strcmp(get(a,'yaxislocation'),'left')
ry(1) = -(maxw+5);
else
ry(1) = axesR(3);
end
ry(2) = -ext(4)/2;
ry(3) = maxw+5;
ry(4) = ry(4) + ext(4);
if ~isempty(yticks)
if ~strcmp(get(a,'yscale'),'log') & ...
((str2num(ylabs(1,:)) ~= yticks(1)) | ...
(str2num(ylabs(end,:)) ~= yticks(end)))
set(label,'string','10^1');
ext = get(label,'extent');
if strcmp(get(a,'xaxislocation'),'bottom')
ry(4) = ry(4) + ext(4);
end
end
end
r = LocalUnionRect(r,ry);
end
% handle x axis tick labels
rx = [0 0 axesR(3) 0];
xlabs = get(a,'xticklabels');
xticks = get(a,'xtick');
if ~isempty(xlabs)
if strcmp(get(a,'xscale'),'log')
set(label,'string',['10^' xlabs(1,:)]);
else
set(label,'string',xlabs(1,:));
end
ext1 = get(label,'extent');
rx(1) = -ext1(3)/2;
if strcmp(get(a,'xscale'),'log')
set(label,'string',['10^' xlabs(size(xlabs,1),:)]);
else
set(label,'string',xlabs(size(xlabs,1),:));
end
ext2 = get(label,'extent');
rx(4) = max(ext1(4),ext2(4));
rx(2) = -rx(4);
rx(3) = axesR(3) + (ext2(3) + ext1(3))/2;
if strcmp(get(a,'xaxislocation'),'top')
rx(2) = rx(2) + axesR(4);
end
if ~isempty(xticks)
if ~strcmp(get(a,'xscale'),'log') & ...
((str2num(xlabs(1,:)) ~= xticks(1)) | ...
(str2num(xlabs(end,:)) ~= xticks(end)))
set(label,'string','10^1');
ext = get(label,'extent');
if strcmp(get(a,'xaxislocation'),'bottom')
rx(4) = rx(4) + ext(4)+5;
rx(2) = rx(2) - ext(4)-5;
else
rx(4) = rx(4) + ext(4)+5 + axesR(4);
rx(2) = rx(2) - ext(4)-5 - axesR(4);
end
end
end
r = LocalUnionRect(r,rx);
end
set(a,'fontunits',oldunits);
delete(label);
end
function c = LocalManualAxesMode(old, allAxes, base)
xs = ['X' base];
ys = ['Y' base];
zs = ['Z' base];
xlog = LocalGetAsCell(allAxes,'xscale');
ylog = LocalGetAsCell(allAxes,'yscale');
zlog = LocalGetAsCell(allAxes,'zscale');
nonlogxflag = logical([]);
nonlogyflag = logical([]);
nonlogzflag = logical([]);
for k = 1:length(xlog)
nonlogxflag(k) = logical(~strcmp(xlog{k},'log'));
nonlogyflag(k) = logical(~strcmp(ylog{k},'log'));
nonlogzflag(k) = logical(~strcmp(zlog{k},'log'));
end
allNonLogXAxes = allAxes(nonlogxflag);
allNonLogYAxes = allAxes(nonlogyflag);
allNonLogZAxes = allAxes(nonlogzflag);
oldXMode = LocalGetAsCell(allNonLogXAxes,xs);
oldYMode = LocalGetAsCell(allNonLogYAxes,ys);
oldZMode = LocalGetAsCell(allNonLogZAxes,zs);
old = LocalPushOldData(old, allNonLogXAxes, {xs}, oldXMode);
old = LocalPushOldData(old, allNonLogYAxes, {ys}, oldYMode);
old = LocalPushOldData(old, allNonLogZAxes, {zs}, oldZMode);
set(allNonLogXAxes,xs,'manual');
set(allNonLogYAxes,ys,'manual');
set(allNonLogZAxes,zs,'manual');
c = old;
function val = LocalCheckAuto(val, auto)
if ischar(val) & strcmp(val,'auto')
val = auto;
end