exportfig.m (31654B)
1 function varargout = exportfig(varargin) 2 %EXPORTFIG Export a figure. 3 % EXPORTFIG(H, FILENAME) writes the figure H to FILENAME. H is 4 % a figure handle and FILENAME is a string that specifies the 5 % name of the output file. 6 % 7 % EXPORTFIG(H, FILENAME, OPTIONS) writes the figure H to FILENAME 8 % with options initially specified by the structure OPTIONS. The 9 % field names of OPTIONS must be legal parameters listed below 10 % and the field values must be legal values for the corresponding 11 % parameter. Default options can be set in releases prior to R12 12 % by storing the OPTIONS structure in the root object's appdata 13 % with the command 14 % setappdata(0,'exportfigdefaults', OPTIONS) 15 % and for releases after R12 by setting the preference with the 16 % command 17 % setpref('exportfig', 'defaults', OPTIONS) 18 % 19 % EXPORTFIG(...,PARAM1,VAL1,PARAM2,VAL2,...) specifies 20 % parameters that control various characteristics of the output 21 % file. Any parameter value can be the string 'auto' which means 22 % the parameter uses the default factory behavior, overriding 23 % any other default for the parameter. 24 % 25 % Format Paramter: 26 % 'Format' a string 27 % specifies the output format. Defaults to 'eps'. For a 28 % list of export formats type 'help print'. 29 % 'Preview' one of the strings 'none', 'tiff' 30 % specifies a preview for EPS files. Defaults to 'none'. 31 % 32 % Size Parameters: 33 % 'Width' a positive scalar 34 % specifies the width in the figure's PaperUnits 35 % 'Height' a positive scalar 36 % specifies the height in the figure's PaperUnits 37 % 'Bounds' one of the strings 'tight', 'loose' 38 % specifies a tight or loose bounding box. Defaults to 'tight'. 39 % 'Reference' an axes handle or a string 40 % specifies that the width and height parameters 41 % are relative to the given axes. If a string is 42 % specified then it must evaluate to an axes handle. 43 % 44 % Specifying only one dimension sets the other dimension 45 % so that the exported aspect ratio is the same as the 46 % figure's or reference axes' current aspect ratio. 47 % If neither dimension is specified the size defaults to 48 % the width and height from the figure's or reference 49 % axes' size. Tight bounding boxes are only computed for 50 % 2-D views and in that case the computed bounds enclose all 51 % text objects. 52 % 53 % Rendering Parameters: 54 % 'Color' one of the strings 'bw', 'gray', 'cmyk' 55 % 'bw' specifies that lines and text are exported in 56 % black and all other objects in grayscale 57 % 'gray' specifies that all objects are exported in grayscale 58 % 'rgb' specifies that all objects are exported in color 59 % using the RGB color space 60 % 'cmyk' specifies that all objects are exported in color 61 % using the CMYK color space 62 % 'Renderer' one of 'painters', 'zbuffer', 'opengl' 63 % specifies the renderer to use 64 % 'Resolution' a positive scalar 65 % specifies the resolution in dots-per-inch. 66 % 'LockAxes' one of 0 or 1 67 % specifies that all axes limits and ticks should be fixed 68 % while exporting. 69 % 70 % The default color setting is 'bw'. 71 % 72 % Font Parameters: 73 % 'FontMode' one of the strings 'scaled', 'fixed' 74 % 'FontSize' a positive scalar 75 % in 'scaled' mode multiplies with the font size of each 76 % text object to obtain the exported font size 77 % in 'fixed' mode specifies the font size of all text 78 % objects in points 79 % 'DefaultFixedFontSize' a positive scalar 80 % in 'fixed' mode specified the default font size in 81 % points 82 % 'FontSizeMin' a positive scalar 83 % specifies the minimum font size allowed after scaling 84 % 'FontSizeMax' a positive scalar 85 % specifies the maximum font size allowed after scaling 86 % 'FontEncoding' one of the strings 'latin1', 'adobe' 87 % specifies the character encoding of the font 88 % 'SeparateText' one of 0 or 1 89 % specifies that the text objects are stored in separate 90 % file as EPS with the base filename having '_t' appended. 91 % 92 % If FontMode is 'scaled' but FontSize is not specified then a 93 % scaling factor is computed from the ratio of the size of the 94 % exported figure to the size of the actual figure. 95 % 96 % The default 'FontMode' setting is 'scaled'. 97 % 98 % Line Width Parameters: 99 % 'LineMode' one of the strings 'scaled', 'fixed' 100 % 'LineWidth' a positive scalar 101 % 'DefaultFixedLineWidth' a positive scalar 102 % 'LineWidthMin' a positive scalar 103 % specifies the minimum line width allowed after scaling 104 % 'LineWidthMax' a positive scalar 105 % specifies the maximum line width allowed after scaling 106 % The semantics of 'Line' parameters are exactly the 107 % same as the corresponding 'Font' parameters, except that 108 % they apply to line widths instead of font sizes. 109 % 110 % Style Map Parameter: 111 % 'LineStyleMap' one of [], 'bw', or a function name or handle 112 % specifies how to map line colors to styles. An empty 113 % style map means styles are not changed. The style map 114 % 'bw' is a built-in mapping that maps lines with the same 115 % color to the same style and otherwise cycles through the 116 % available styles. A user-specified map is a function 117 % that takes as input a cell array of line objects and 118 % outputs a cell array of line style strings. The default 119 % map is []. 120 % 121 % Examples: 122 % exportfig(gcf,'fig1.eps','height',3); 123 % Exports the current figure to the file named 'fig1.eps' with 124 % a height of 3 inches (assuming the figure's PaperUnits is 125 % inches) and an aspect ratio the same as the figure's aspect 126 % ratio on screen. 127 % 128 % opts = struct('FontMode','fixed','FontSize',10,'height',3); 129 % exportfig(gcf, 'fig2.eps', opts, 'height', 5); 130 % Exports the current figure to 'fig2.eps' with all 131 % text in 10 point fonts and with height 5 inches. 132 % 133 % See also PREVIEWFIG, APPLYTOFIG, RESTOREFIG, PRINT. 134 135 % Copyright 2000 Ben Hinkle 136 % Email bug reports and comments to bhinkle@mathworks.com 137 138 if (nargin < 2) 139 error('Too few input arguments'); 140 end 141 142 % exportfig(H, filename, [options,] ...) 143 H = varargin{1}; 144 if ~LocalIsHG(H,'figure') 145 error('First argument must be a handle to a figure.'); 146 end 147 filename = varargin{2}; 148 if ~ischar(filename) 149 error('Second argument must be a string.'); 150 end 151 paramPairs = {varargin{3:end}}; 152 if nargin > 2 153 if isstruct(paramPairs{1}) 154 pcell = LocalToCell(paramPairs{1}); 155 paramPairs = {pcell{:}, paramPairs{2:end}}; 156 end 157 end 158 verstr = version; 159 majorver = str2num(verstr(1)); 160 defaults = []; 161 if majorver > 5 162 if ispref('exportfig','defaults') 163 defaults = getpref('exportfig','defaults'); 164 end 165 elseif exist('getappdata') 166 defaults = getappdata(0,'exportfigdefaults'); 167 end 168 if ~isempty(defaults) 169 dcell = LocalToCell(defaults); 170 paramPairs = {dcell{:}, paramPairs{:}}; 171 end 172 173 % Do some validity checking on param-value pairs 174 if (rem(length(paramPairs),2) ~= 0) 175 error(['Invalid input syntax. Optional parameters and values' ... 176 ' must be in pairs.']); 177 end 178 179 auto.format = 'eps'; 180 auto.preview = 'none'; 181 auto.width = -1; 182 auto.height = -1; 183 auto.color = 'bw'; 184 auto.defaultfontsize=10; 185 auto.fontsize = -1; 186 auto.fontmode='scaled'; 187 auto.fontmin = 8; 188 auto.fontmax = 60; 189 auto.defaultlinewidth = 1.0; 190 auto.linewidth = -1; 191 auto.linemode=[]; 192 auto.linemin = 0.5; 193 auto.linemax = 100; 194 auto.fontencoding = 'latin1'; 195 auto.renderer = []; 196 auto.resolution = []; 197 auto.stylemap = []; 198 auto.applystyle = 0; 199 auto.refobj = -1; 200 auto.bounds = 'tight'; 201 explicitbounds = 0; 202 auto.lockaxes = 1; 203 auto.separatetext = 0; 204 opts = auto; 205 206 % Process param-value pairs 207 args = {}; 208 for k = 1:2:length(paramPairs) 209 param = lower(paramPairs{k}); 210 if ~ischar(param) 211 error('Optional parameter names must be strings'); 212 end 213 value = paramPairs{k+1}; 214 215 switch (param) 216 case 'format' 217 opts.format = LocalCheckAuto(lower(value),auto.format); 218 if strcmp(opts.format,'preview') 219 error(['Format ''preview'' no longer supported. Use PREVIEWFIG' ... 220 ' instead.']); 221 end 222 case 'preview' 223 opts.preview = LocalCheckAuto(lower(value),auto.preview); 224 if ~strcmp(opts.preview,{'none','tiff'}) 225 error('Preview must be ''none'' or ''tiff''.'); 226 end 227 case 'width' 228 opts.width = LocalToNum(value, auto.width); 229 if ~ischar(value) | ~strcmp(value,'auto') 230 if ~LocalIsPositiveScalar(opts.width) 231 error('Width must be a numeric scalar > 0'); 232 end 233 end 234 case 'height' 235 opts.height = LocalToNum(value, auto.height); 236 if ~ischar(value) | ~strcmp(value,'auto') 237 if(~LocalIsPositiveScalar(opts.height)) 238 error('Height must be a numeric scalar > 0'); 239 end 240 end 241 case 'color' 242 opts.color = LocalCheckAuto(lower(value),auto.color); 243 if ~strcmp(opts.color,{'bw','gray','rgb','cmyk'}) 244 error('Color must be ''bw'', ''gray'',''rgb'' or ''cmyk''.'); 245 end 246 case 'fontmode' 247 opts.fontmode = LocalCheckAuto(lower(value),auto.fontmode); 248 if ~strcmp(opts.fontmode,{'scaled','fixed'}) 249 error('FontMode must be ''scaled'' or ''fixed''.'); 250 end 251 case 'fontsize' 252 opts.fontsize = LocalToNum(value,auto.fontsize); 253 if ~ischar(value) | ~strcmp(value,'auto') 254 if ~LocalIsPositiveScalar(opts.fontsize) 255 error('FontSize must be a numeric scalar > 0'); 256 end 257 end 258 case 'defaultfixedfontsize' 259 opts.defaultfontsize = LocalToNum(value,auto.defaultfontsize); 260 if ~ischar(value) | ~strcmp(value,'auto') 261 if ~LocalIsPositiveScalar(opts.defaultfontsize) 262 error('DefaultFixedFontSize must be a numeric scalar > 0'); 263 end 264 end 265 case 'fontsizemin' 266 opts.fontmin = LocalToNum(value,auto.fontmin); 267 if ~ischar(value) | ~strcmp(value,'auto') 268 if ~LocalIsPositiveScalar(opts.fontmin) 269 error('FontSizeMin must be a numeric scalar > 0'); 270 end 271 end 272 case 'fontsizemax' 273 opts.fontmax = LocalToNum(value,auto.fontmax); 274 if ~ischar(value) | ~strcmp(value,'auto') 275 if ~LocalIsPositiveScalar(opts.fontmax) 276 error('FontSizeMax must be a numeric scalar > 0'); 277 end 278 end 279 case 'fontencoding' 280 opts.fontencoding = LocalCheckAuto(lower(value),auto.fontencoding); 281 if ~strcmp(opts.fontencoding,{'latin1','adobe'}) 282 error('FontEncoding must be ''latin1'' or ''adobe''.'); 283 end 284 case 'linemode' 285 opts.linemode = LocalCheckAuto(lower(value),auto.linemode); 286 if ~strcmp(opts.linemode,{'scaled','fixed'}) 287 error('LineMode must be ''scaled'' or ''fixed''.'); 288 end 289 case 'linewidth' 290 opts.linewidth = LocalToNum(value,auto.linewidth); 291 if ~ischar(value) | ~strcmp(value,'auto') 292 if ~LocalIsPositiveScalar(opts.linewidth) 293 error('LineWidth must be a numeric scalar > 0'); 294 end 295 end 296 case 'defaultfixedlinewidth' 297 opts.defaultlinewidth = LocalToNum(value,auto.defaultlinewidth); 298 if ~ischar(value) | ~strcmp(value,'auto') 299 if ~LocalIsPositiveScalar(opts.defaultlinewidth) 300 error(['DefaultFixedLineWidth must be a numeric scalar >' ... 301 ' 0']); 302 end 303 end 304 case 'linewidthmin' 305 opts.linemin = LocalToNum(value,auto.linemin); 306 if ~ischar(value) | ~strcmp(value,'auto') 307 if ~LocalIsPositiveScalar(opts.linemin) 308 error('LineWidthMin must be a numeric scalar > 0'); 309 end 310 end 311 case 'linewidthmax' 312 opts.linemax = LocalToNum(value,auto.linemax); 313 if ~ischar(value) | ~strcmp(value,'auto') 314 if ~LocalIsPositiveScalar(opts.linemax) 315 error('LineWidthMax must be a numeric scalar > 0'); 316 end 317 end 318 case 'linestylemap' 319 opts.stylemap = LocalCheckAuto(value,auto.stylemap); 320 case 'renderer' 321 opts.renderer = LocalCheckAuto(lower(value),auto.renderer); 322 if ~ischar(value) | ~strcmp(value,'auto') 323 if ~strcmp(opts.renderer,{'painters','zbuffer','opengl'}) 324 error(['Renderer must be ''painters'', ''zbuffer'' or' ... 325 ' ''opengl''.']); 326 end 327 end 328 case 'resolution' 329 opts.resolution = LocalToNum(value,auto.resolution); 330 if ~ischar(value) | ~strcmp(value,'auto') 331 if ~(isnumeric(value) & (prod(size(value)) == 1) & (value >= 0)); 332 error('Resolution must be a numeric scalar >= 0'); 333 end 334 end 335 case 'applystyle' % means to apply the options and not export 336 opts.applystyle = 1; 337 case 'reference' 338 if ischar(value) 339 if strcmp(value,'auto') 340 opts.refobj = auto.refobj; 341 else 342 opts.refobj = eval(value); 343 end 344 else 345 opts.refobj = value; 346 end 347 if ~LocalIsHG(opts.refobj,'axes') 348 error('Reference object must evaluate to an axes handle.'); 349 end 350 case 'bounds' 351 opts.bounds = LocalCheckAuto(lower(value),auto.bounds); 352 explicitbounds = 1; 353 if ~strcmp(opts.bounds,{'tight','loose'}) 354 error('Bounds must be ''tight'' or ''loose''.'); 355 end 356 case 'lockaxes' 357 opts.lockaxes = LocalToNum(value,auto.lockaxes); 358 case 'separatetext' 359 opts.separatetext = LocalToNum(value,auto.separatetext); 360 otherwise 361 error(['Unrecognized option ' param '.']); 362 end 363 end 364 365 % make sure figure is up-to-date 366 drawnow; 367 368 allLines = findall(H, 'type', 'line'); 369 allText = findall(H, 'type', 'text'); 370 allAxes = findall(H, 'type', 'axes'); 371 allImages = findall(H, 'type', 'image'); 372 allLights = findall(H, 'type', 'light'); 373 allPatch = findall(H, 'type', 'patch'); 374 allSurf = findall(H, 'type', 'surface'); 375 allRect = findall(H, 'type', 'rectangle'); 376 allFont = [allText; allAxes]; 377 allColor = [allLines; allText; allAxes; allLights]; 378 allMarker = [allLines; allPatch; allSurf]; 379 allEdge = [allPatch; allSurf]; 380 allCData = [allImages; allPatch; allSurf]; 381 382 old.objs = {}; 383 old.prop = {}; 384 old.values = {}; 385 386 % Process format 387 if strncmp(opts.format,'eps',3) & ~strcmp(opts.preview,'none') 388 args = {args{:}, ['-' opts.preview]}; 389 end 390 391 hadError = 0; 392 oldwarn = warning; 393 try 394 395 % lock axes limits, ticks and labels if requested 396 if opts.lockaxes 397 old = LocalManualAxesMode(old, allAxes, 'TickMode'); 398 old = LocalManualAxesMode(old, allAxes, 'TickLabelMode'); 399 old = LocalManualAxesMode(old, allAxes, 'LimMode'); 400 end 401 402 % Process size parameters 403 figurePaperUnits = get(H, 'PaperUnits'); 404 oldFigureUnits = get(H, 'Units'); 405 oldFigPos = get(H,'Position'); 406 set(H, 'Units', figurePaperUnits); 407 figPos = get(H,'Position'); 408 refsize = figPos(3:4); 409 if opts.refobj ~= -1 410 oldUnits = get(opts.refobj, 'Units'); 411 set(opts.refobj, 'Units', figurePaperUnits); 412 r = get(opts.refobj, 'Position'); 413 refsize = r(3:4); 414 set(opts.refobj, 'Units', oldUnits); 415 end 416 aspectRatio = refsize(1)/refsize(2); 417 if (opts.width == -1) & (opts.height == -1) 418 opts.width = refsize(1); 419 opts.height = refsize(2); 420 elseif (opts.width == -1) 421 opts.width = opts.height * aspectRatio; 422 elseif (opts.height == -1) 423 opts.height = opts.width / aspectRatio; 424 end 425 wscale = opts.width/refsize(1); 426 hscale = opts.height/refsize(2); 427 sizescale = min(wscale,hscale); 428 old = LocalPushOldData(old,H,'PaperPositionMode', ... 429 get(H,'PaperPositionMode')); 430 set(H, 'PaperPositionMode', 'auto'); 431 newPos = [figPos(1) figPos(2)+figPos(4)*(1-hscale) ... 432 wscale*figPos(3) hscale*figPos(4)]; 433 set(H, 'Position', newPos); 434 set(H, 'Units', oldFigureUnits); 435 436 % process line-style map 437 if ~isempty(opts.stylemap) & ~isempty(allLines) 438 oldlstyle = LocalGetAsCell(allLines,'LineStyle'); 439 old = LocalPushOldData(old, allLines, {'LineStyle'}, ... 440 oldlstyle); 441 newlstyle = oldlstyle; 442 if ischar(opts.stylemap) & strcmpi(opts.stylemap,'bw') 443 newlstyle = LocalMapColorToStyle(allLines); 444 else 445 try 446 newlstyle = feval(opts.stylemap,allLines); 447 catch 448 warning(['Skipping stylemap. ' lasterr]); 449 end 450 end 451 set(allLines,{'LineStyle'},newlstyle); 452 end 453 454 % Process rendering parameters 455 switch (opts.color) 456 case {'bw', 'gray'} 457 if ~strcmp(opts.color,'bw') & strncmp(opts.format,'eps',3) 458 opts.format = [opts.format 'c']; 459 end 460 args = {args{:}, ['-d' opts.format]}; 461 462 %compute and set gray colormap 463 oldcmap = get(H,'Colormap'); 464 newgrays = 0.30*oldcmap(:,1) + 0.59*oldcmap(:,2) + 0.11*oldcmap(:,3); 465 newcmap = [newgrays newgrays newgrays]; 466 old = LocalPushOldData(old, H, 'Colormap', oldcmap); 467 set(H, 'Colormap', newcmap); 468 469 %compute and set ColorSpec and CData properties 470 old = LocalUpdateColors(allColor, 'color', old); 471 old = LocalUpdateColors(allAxes, 'xcolor', old); 472 old = LocalUpdateColors(allAxes, 'ycolor', old); 473 old = LocalUpdateColors(allAxes, 'zcolor', old); 474 old = LocalUpdateColors(allMarker, 'MarkerEdgeColor', old); 475 old = LocalUpdateColors(allMarker, 'MarkerFaceColor', old); 476 old = LocalUpdateColors(allEdge, 'EdgeColor', old); 477 old = LocalUpdateColors(allEdge, 'FaceColor', old); 478 old = LocalUpdateColors(allCData, 'CData', old); 479 480 case {'rgb','cmyk'} 481 if strncmp(opts.format,'eps',3) 482 opts.format = [opts.format 'c']; 483 args = {args{:}, ['-d' opts.format]}; 484 if strcmp(opts.color,'cmyk') 485 args = {args{:}, '-cmyk'}; 486 end 487 else 488 args = {args{:}, ['-d' opts.format]}; 489 end 490 otherwise 491 error('Invalid Color parameter'); 492 end 493 if (~isempty(opts.renderer)) 494 args = {args{:}, ['-' opts.renderer]}; 495 end 496 if (~isempty(opts.resolution)) | ~strncmp(opts.format,'eps',3) 497 if isempty(opts.resolution) 498 opts.resolution = 0; 499 end 500 args = {args{:}, ['-r' int2str(opts.resolution)]}; 501 end 502 503 % Process font parameters 504 if ~isempty(opts.fontmode) 505 oldfonts = LocalGetAsCell(allFont,'FontSize'); 506 oldfontunits = LocalGetAsCell(allFont,'FontUnits'); 507 set(allFont,'FontUnits','points'); 508 switch (opts.fontmode) 509 case 'fixed' 510 if (opts.fontsize == -1) 511 set(allFont,'FontSize',opts.defaultfontsize); 512 else 513 set(allFont,'FontSize',opts.fontsize); 514 end 515 case 'scaled' 516 if (opts.fontsize == -1) 517 scale = sizescale; 518 else 519 scale = opts.fontsize; 520 end 521 newfonts = LocalScale(oldfonts,scale,opts.fontmin,opts.fontmax); 522 set(allFont,{'FontSize'},newfonts); 523 otherwise 524 error('Invalid FontMode parameter'); 525 end 526 old = LocalPushOldData(old, allFont, {'FontSize'}, oldfonts); 527 old = LocalPushOldData(old, allFont, {'FontUnits'}, oldfontunits); 528 end 529 if strcmp(opts.fontencoding,'adobe') & strncmp(opts.format,'eps',3) 530 args = {args{:}, '-adobecset'}; 531 end 532 533 % Process line parameters 534 if ~isempty(opts.linemode) 535 oldlines = LocalGetAsCell(allMarker,'LineWidth'); 536 old = LocalPushOldData(old, allMarker, {'LineWidth'}, oldlines); 537 switch (opts.linemode) 538 case 'fixed' 539 if (opts.linewidth == -1) 540 set(allMarker,'LineWidth',opts.defaultlinewidth); 541 else 542 set(allMarker,'LineWidth',opts.linewidth); 543 end 544 case 'scaled' 545 if (opts.linewidth == -1) 546 scale = sizescale; 547 else 548 scale = opts.linewidth; 549 end 550 newlines = LocalScale(oldlines, scale, opts.linemin, opts.linemax); 551 set(allMarker,{'LineWidth'},newlines); 552 end 553 end 554 555 % adjust figure bounds to surround axes 556 if strcmp(opts.bounds,'tight') 557 if (~strncmp(opts.format,'eps',3) & LocalHas3DPlot(allAxes)) | ... 558 (strncmp(opts.format,'eps',3) & opts.separatetext) 559 if (explicitbounds == 1) 560 warning(['Cannot compute ''tight'' bounds. Using ''loose''' ... 561 ' bounds.']); 562 end 563 opts.bounds = 'loose'; 564 end 565 end 566 warning('off'); 567 if ~isempty(allAxes) 568 if strncmp(opts.format,'eps',3) 569 if strcmp(opts.bounds,'loose') 570 args = {args{:}, '-loose'}; 571 end 572 old = LocalPushOldData(old,H,'Position', oldFigPos); 573 elseif strcmp(opts.bounds,'tight') 574 oldaunits = LocalGetAsCell(allAxes,'Units'); 575 oldapos = LocalGetAsCell(allAxes,'Position'); 576 oldtunits = LocalGetAsCell(allText,'units'); 577 oldtpos = LocalGetAsCell(allText,'Position'); 578 set(allAxes,'units','points'); 579 apos = LocalGetAsCell(allAxes,'Position'); 580 oldunits = get(H,'Units'); 581 set(H,'units','points'); 582 origfr = get(H,'position'); 583 fr = []; 584 for k=1:length(allAxes) 585 if ~strcmpi(get(allAxes(k),'Tag'),'legend') 586 axesR = apos{k}; 587 r = LocalAxesTightBoundingBox(axesR, allAxes(k)); 588 r(1:2) = r(1:2) + axesR(1:2); 589 fr = LocalUnionRect(fr,r); 590 end 591 end 592 if isempty(fr) 593 fr = [0 0 origfr(3:4)]; 594 end 595 for k=1:length(allAxes) 596 ax = allAxes(k); 597 r = apos{k}; 598 r(1:2) = r(1:2) - fr(1:2); 599 set(ax,'Position',r); 600 end 601 old = LocalPushOldData(old, allAxes, {'Position'}, oldapos); 602 old = LocalPushOldData(old, allText, {'Position'}, oldtpos); 603 old = LocalPushOldData(old, allText, {'Units'}, oldtunits); 604 old = LocalPushOldData(old, allAxes, {'Units'}, oldaunits); 605 old = LocalPushOldData(old, H, 'Position', oldFigPos); 606 old = LocalPushOldData(old, H, 'Units', oldFigureUnits); 607 r = [origfr(1) origfr(2)+origfr(4)-fr(4) fr(3:4)]; 608 set(H,'Position',r); 609 else 610 args = {args{:}, '-loose'}; 611 old = LocalPushOldData(old,H,'Position', oldFigPos); 612 end 613 end 614 615 % Process text in a separate file if needed 616 if opts.separatetext & ~opts.applystyle 617 % First hide all text and export 618 oldtvis = LocalGetAsCell(allText,'visible'); 619 set(allText,'visible','off'); 620 oldax = LocalGetAsCell(allAxes,'XTickLabel',1); 621 olday = LocalGetAsCell(allAxes,'YTickLabel',1); 622 oldaz = LocalGetAsCell(allAxes,'ZTickLabel',1); 623 null = cell(length(oldax),1); 624 [null{:}] = deal([]); 625 set(allAxes,{'XTickLabel'},null); 626 set(allAxes,{'YTickLabel'},null); 627 set(allAxes,{'ZTickLabel'},null); 628 print(H, filename, args{:}); 629 set(allText,{'Visible'},oldtvis); 630 set(allAxes,{'XTickLabel'},oldax); 631 set(allAxes,{'YTickLabel'},olday); 632 set(allAxes,{'ZTickLabel'},oldaz); 633 % Now hide all non-text and export as eps in painters 634 [path, name, ext] = fileparts(filename); 635 tfile = fullfile(path,[name '_t.eps']); 636 tfile2 = fullfile(path,[name '_t2.eps']); 637 foundRenderer = 0; 638 for k=1:length(args) 639 if strncmp('-d',args{k},2) 640 args{k} = '-deps'; 641 elseif strncmp('-zbuffer',args{k},8) | ... 642 strncmp('-opengl', args{k},6) 643 args{k} = '-painters'; 644 foundRenderer = 1; 645 end 646 end 647 if ~foundRenderer 648 args = {args{:}, '-painters'}; 649 end 650 allNonText = [allLines; allLights; allPatch; ... 651 allImages; allSurf; allRect]; 652 oldvis = LocalGetAsCell(allNonText,'visible'); 653 oldc = LocalGetAsCell(allAxes,'color'); 654 oldaxg = LocalGetAsCell(allAxes,'XGrid'); 655 oldayg = LocalGetAsCell(allAxes,'YGrid'); 656 oldazg = LocalGetAsCell(allAxes,'ZGrid'); 657 [null{:}] = deal('off'); 658 set(allAxes,{'XGrid'},null); 659 set(allAxes,{'YGrid'},null); 660 set(allAxes,{'ZGrid'},null); 661 set(allNonText,'Visible','off'); 662 set(allAxes,'Color','none'); 663 print(H, tfile2, args{:}); 664 set(allNonText,{'Visible'},oldvis); 665 set(allAxes,{'Color'},oldc); 666 set(allAxes,{'XGrid'},oldaxg); 667 set(allAxes,{'YGrid'},oldayg); 668 set(allAxes,{'ZGrid'},oldazg); 669 %hack up the postscript file 670 fid1 = fopen(tfile,'w'); 671 fid2 = fopen(tfile2,'r'); 672 line = fgetl(fid2); 673 while ischar(line) 674 if strncmp(line,'%%Title',7) 675 fprintf(fid1,'%s\n',['%%Title: ', tfile]); 676 elseif (length(line) < 3) 677 fprintf(fid1,'%s\n',line); 678 elseif ~strcmp(line(end-2:end),' PR') & ... 679 ~strcmp(line(end-1:end),' L') 680 fprintf(fid1,'%s\n',line); 681 end 682 line = fgetl(fid2); 683 end 684 fclose(fid1); 685 fclose(fid2); 686 delete(tfile2); 687 688 elseif ~opts.applystyle 689 drawnow; 690 print(H, filename, args{:}); 691 end 692 warning(oldwarn); 693 694 catch 695 warning(oldwarn); 696 hadError = 1; 697 end 698 699 % Restore figure settings 700 if opts.applystyle 701 varargout{1} = old; 702 else 703 for n=1:length(old.objs) 704 if ~iscell(old.values{n}) & iscell(old.prop{n}) 705 old.values{n} = {old.values{n}}; 706 end 707 set(old.objs{n}, old.prop{n}, old.values{n}); 708 end 709 end 710 711 if hadError 712 error(deblank(lasterr)); 713 end 714 715 % 716 % Local Functions 717 % 718 719 function outData = LocalPushOldData(inData, objs, prop, values) 720 outData.objs = {objs, inData.objs{:}}; 721 outData.prop = {prop, inData.prop{:}}; 722 outData.values = {values, inData.values{:}}; 723 724 function cellArray = LocalGetAsCell(fig,prop,allowemptycell); 725 cellArray = get(fig,prop); 726 if nargin < 3 727 allowemptycell = 0; 728 end 729 if ~iscell(cellArray) & (allowemptycell | ~isempty(cellArray)) 730 cellArray = {cellArray}; 731 end 732 733 function newArray = LocalScale(inArray, scale, minv, maxv) 734 n = length(inArray); 735 newArray = cell(n,1); 736 for k=1:n 737 newArray{k} = min(maxv,max(minv,scale*inArray{k}(1))); 738 end 739 740 function gray = LocalMapToGray1(color) 741 gray = color; 742 if ischar(color) 743 switch color(1) 744 case 'y' 745 color = [1 1 0]; 746 case 'm' 747 color = [1 0 1]; 748 case 'c' 749 color = [0 1 1]; 750 case 'r' 751 color = [1 0 0]; 752 case 'g' 753 color = [0 1 0]; 754 case 'b' 755 color = [0 0 1]; 756 case 'w' 757 color = [1 1 1]; 758 case 'k' 759 color = [0 0 0]; 760 end 761 end 762 if ~ischar(color) 763 gray = 0.30*color(1) + 0.59*color(2) + 0.11*color(3); 764 end 765 766 function newArray = LocalMapToGray(inArray); 767 n = length(inArray); 768 newArray = cell(n,1); 769 for k=1:n 770 color = inArray{k}; 771 if ~isempty(color) 772 color = LocalMapToGray1(color); 773 end 774 if isempty(color) | ischar(color) 775 newArray{k} = color; 776 else 777 newArray{k} = [color color color]; 778 end 779 end 780 781 function newArray = LocalMapColorToStyle(inArray); 782 inArray = LocalGetAsCell(inArray,'Color'); 783 n = length(inArray); 784 newArray = cell(n,1); 785 styles = {'-','--',':','-.'}; 786 uniques = []; 787 nstyles = length(styles); 788 for k=1:n 789 gray = LocalMapToGray1(inArray{k}); 790 if isempty(gray) | ischar(gray) | gray < .05 791 newArray{k} = '-'; 792 else 793 if ~isempty(uniques) & any(gray == uniques) 794 ind = find(gray==uniques); 795 else 796 uniques = [uniques gray]; 797 ind = length(uniques); 798 end 799 newArray{k} = styles{mod(ind-1,nstyles)+1}; 800 end 801 end 802 803 function newArray = LocalMapCData(inArray); 804 n = length(inArray); 805 newArray = cell(n,1); 806 for k=1:n 807 color = inArray{k}; 808 if (ndims(color) == 3) & isa(color,'double') 809 gray = 0.30*color(:,:,1) + 0.59*color(:,:,2) + 0.11*color(:,:,3); 810 color(:,:,1) = gray; 811 color(:,:,2) = gray; 812 color(:,:,3) = gray; 813 end 814 newArray{k} = color; 815 end 816 817 function outData = LocalUpdateColors(inArray, prop, inData) 818 value = LocalGetAsCell(inArray,prop); 819 outData.objs = {inData.objs{:}, inArray}; 820 outData.prop = {inData.prop{:}, {prop}}; 821 outData.values = {inData.values{:}, value}; 822 if (~isempty(value)) 823 if strcmp(prop,'CData') 824 value = LocalMapCData(value); 825 else 826 value = LocalMapToGray(value); 827 end 828 set(inArray,{prop},value); 829 end 830 831 function bool = LocalIsPositiveScalar(value) 832 bool = isnumeric(value) & ... 833 prod(size(value)) == 1 & ... 834 value > 0; 835 836 function value = LocalToNum(value,auto) 837 if ischar(value) 838 if strcmp(value,'auto') 839 value = auto; 840 else 841 value = str2num(value); 842 end 843 end 844 845 %convert a struct to {field1,val1,field2,val2,...} 846 function c = LocalToCell(s) 847 f = fieldnames(s); 848 v = struct2cell(s); 849 opts = cell(2,length(f)); 850 opts(1,:) = f; 851 opts(2,:) = v; 852 c = {opts{:}}; 853 854 function c = LocalIsHG(obj,hgtype) 855 c = 0; 856 if (length(obj) == 1) & ishandle(obj) 857 c = strcmp(get(obj,'type'),hgtype); 858 end 859 860 function c = LocalHas3DPlot(a) 861 zticks = LocalGetAsCell(a,'ZTickLabel'); 862 c = 0; 863 for k=1:length(zticks) 864 if ~isempty(zticks{k}) 865 c = 1; 866 return; 867 end 868 end 869 870 function r = LocalUnionRect(r1,r2) 871 if isempty(r1) 872 r = r2; 873 elseif isempty(r2) 874 r = r1; 875 elseif max(r2(3:4)) > 0 876 left = min(r1(1),r2(1)); 877 bot = min(r1(2),r2(2)); 878 right = max(r1(1)+r1(3),r2(1)+r2(3)); 879 top = max(r1(2)+r1(4),r2(2)+r2(4)); 880 r = [left bot right-left top-bot]; 881 else 882 r = r1; 883 end 884 885 function c = LocalLabelsMatchTicks(labs,ticks) 886 c = 0; 887 try 888 t1 = num2str(ticks(1)); 889 n = length(ticks); 890 tend = num2str(ticks(n)); 891 c = strncmp(labs(1),t1,length(labs(1))) & ... 892 strncmp(labs(n),tend,length(labs(n))); 893 end 894 895 function r = LocalAxesTightBoundingBox(axesR, a) 896 r = []; 897 atext = findall(a,'type','text','visible','on'); 898 if ~isempty(atext) 899 set(atext,'units','points'); 900 res=LocalGetAsCell(atext,'extent'); 901 for n=1:length(atext) 902 r = LocalUnionRect(r,res{n}); 903 end 904 end 905 if strcmp(get(a,'visible'),'on') 906 r = LocalUnionRect(r,[0 0 axesR(3:4)]); 907 oldunits = get(a,'fontunits'); 908 set(a,'fontunits','points'); 909 label = text(0,0,'','parent',a,... 910 'units','points',... 911 'fontsize',get(a,'fontsize'),... 912 'fontname',get(a,'fontname'),... 913 'fontweight',get(a,'fontweight'),... 914 'fontangle',get(a,'fontangle'),... 915 'visible','off'); 916 fs = get(a,'fontsize'); 917 918 % handle y axis tick labels 919 ry = [0 -fs/2 0 axesR(4)+fs]; 920 ylabs = get(a,'yticklabels'); 921 yticks = get(a,'ytick'); 922 maxw = 0; 923 if ~isempty(ylabs) 924 for n=1:size(ylabs,1) 925 set(label,'string',ylabs(n,:)); 926 ext = get(label,'extent'); 927 maxw = max(maxw,ext(3)); 928 end 929 if ~LocalLabelsMatchTicks(ylabs,yticks) & ... 930 strcmp(get(a,'xaxislocation'),'bottom') 931 ry(4) = ry(4) + 1.5*ext(4); 932 end 933 if strcmp(get(a,'yaxislocation'),'left') 934 ry(1) = -(maxw+5); 935 else 936 ry(1) = axesR(3); 937 end 938 ry(3) = maxw+5; 939 r = LocalUnionRect(r,ry); 940 end 941 942 % handle x axis tick labels 943 rx = [0 0 0 fs+5]; 944 xlabs = get(a,'xticklabels'); 945 xticks = get(a,'xtick'); 946 if ~isempty(xlabs) 947 if strcmp(get(a,'xaxislocation'),'bottom') 948 rx(2) = -(fs+5); 949 if ~LocalLabelsMatchTicks(xlabs,xticks); 950 rx(4) = rx(4) + 2*fs; 951 rx(2) = rx(2) - 2*fs; 952 end 953 else 954 rx(2) = axesR(4); 955 % exponent is still below axes 956 if ~LocalLabelsMatchTicks(xlabs,xticks); 957 rx(4) = rx(4) + axesR(4) + 2*fs; 958 rx(2) = -2*fs; 959 end 960 end 961 set(label,'string',xlabs(1,:)); 962 ext1 = get(label,'extent'); 963 rx(1) = -ext1(3)/2; 964 set(label,'string',xlabs(size(xlabs,1),:)); 965 ext2 = get(label,'extent'); 966 rx(3) = axesR(3) + (ext2(3) + ext1(3))/2; 967 r = LocalUnionRect(r,rx); 968 end 969 set(a,'fontunits',oldunits); 970 delete(label); 971 end 972 973 function c = LocalManualAxesMode(old, allAxes, base) 974 xs = ['X' base]; 975 ys = ['Y' base]; 976 zs = ['Z' base]; 977 oldXMode = LocalGetAsCell(allAxes,xs); 978 oldYMode = LocalGetAsCell(allAxes,ys); 979 oldZMode = LocalGetAsCell(allAxes,zs); 980 old = LocalPushOldData(old, allAxes, {xs}, oldXMode); 981 old = LocalPushOldData(old, allAxes, {ys}, oldYMode); 982 old = LocalPushOldData(old, allAxes, {zs}, oldZMode); 983 set(allAxes,xs,'manual'); 984 set(allAxes,ys,'manual'); 985 set(allAxes,zs,'manual'); 986 c = old; 987 988 function val = LocalCheckAuto(val, auto) 989 if ischar(val) & strcmp(val,'auto') 990 val = auto; 991 end