function fig2mfile(fig,fn)
% FIG2MFILE - save a figure as an executable mfile
%
% USAGE: fig2mfile(fig,'myfig')
%
% fig = figure number of figure to be saved
% 'myfig' = desired mfile name
%
% NOTES: (1) Most plots and images can be saved. Most data types can
% now be handled, including multi-level and multi-dimensional
% structs and cell arrays. In tests, GUIs can be handled;
% however, saving a GUI figure window does not save
% its associated callback functions and cannot preserve
% the numerical value of handles (since they are regenerated
% at the each figure creation).
% (2) To answer the inevitable question, this function will be
% needed by authors who don't want to include a separate
% saved figure file in a release of their software, but would
% rather include the figure generation in their code (e.g. for
% a compiled software release).
% (3) Complex figures can take a few minutes to reduce to m-file
% format. Disk usage greatly increases from fig-file format
% as one might expect. (Incidentally, zip-file compression
% reduces the size to roughly comparable with fig-file size.)
% (4) The generated mfile contains a single function ("drawfig")
% which can be moved into other code as needed.
% (5) The created function returns a handle to the figure when it
% is executed.
% (6) ver 1.0: initial writing, Michael Kleder, July 2005
% (7) ver 2.0: accept new & multi-level datatypes,
% Michael Kleder, Oct 2005
%
% EXAMPLE:
%
% surf(peaks+peaks.^2)
% title('Squared Peaks')
% fig2mfile(gcf,'mypeaks')
% close all
% h=mypeaks
[p,n,ex,v]=fileparts(fn);
ex='.m';
fn=fullfile(p,[n ex v]);
fid=fopen(fn,'w');
if fid== -1
error(['Cannot open "' fn '" to write.'])
end
fprintf(fid,'function h=drawfig\n');
fprintf(fid,'%% This code was auto-generated by FIG2MFILE version 2.0\n');
fprintf(fid,'%% FIG2MFILE ver 2.0 was written by Michael Kleder, Oct 2005.\n');
s=handle2struct(fig);
qq=whos('s');
fprintf(['Matlab figure data requires ' num2str(qq.bytes) ' bytes. (M-file will be larger.)\n']);
q=dissect(s);
for n=1:length(q)
show(eval(q{n}),q{n},fid)
end
fprintf(fid,'h=struct2handle(s,0);\n');
fprintf(fid,'return\n');
fclose(fid);
return
function show(s,nm,fid)
if ~isstruct(s)
fprintf(fid,[nm ' = ']);
csw = class(s);
if strcmp(csw,'char')
s = double(s);
end
fprintf(fid,[csw '(']); % declare class and open paren
if length(size(s))>2 % MULTIDIMENSIONAL
fprintf(fid,'cat(3,');
for pg = 1:size(s,3)
fprintf(fid,'[');
for row=1:size(s,1)
for col=1:size(s,2)
if ~mod(col,6)
fprintf(fid,' ...\n');
end
fprintf(fid,[' ' num2str(s(row,col,pg),18)]);
end
fprintf(fid,';\n');
end
fprintf(fid,']');
if pg < size(s,3)
fprintf(fid,',');
end
end
fprintf(fid,'));\n'); % close parens and terminate line
else % UNIDIMENSIONAL
fprintf(fid,'[');
for row=1:size(s,1)
for col=1:size(s,2)
if ~mod(col,6)
fprintf(fid,' ...\n');
end
fprintf(fid,[' ' num2str(s(row,col),18)]);
end
fprintf(fid,';');
if row < size(s,1)
fprintf(fid,'\n');
end
end
fprintf(fid,']);\n'); % close paren and terminate line
end % end of test for multidimensionality
else % quantity is a struct
ss = size(s);
while ss(end) == 1 & length(ss) > 1
ss(end)=[];
end
if length(ss) > 1
error('Multidimensional struct encountered. Exiting.')
end
for ssi = 1:ss
f=fields(s(ssi));
q=f';
for r=q
t=r{1};
nmt = [nm '(' num2str(ssi) ').' t];
show(getfield(s(ssi),t),nmt,fid);
end
end
end
return
function q=dissect(s)
nm = inputname(1);
if isempty(s)
q=nm;
return
end
q=getkids(s,'s');
for n=1:length(q)
q{n}=[nm q{n}];
end
return
function q=getkids(s,mn) % recurse sub items for cells & structs
q={};
if iscell(s)
dims = length(size(s));
for n = 1:prod(size(s))
[d{1:dims}]=ind2sub(size(s),n);
dn=[];
for j=1:dims
dn=[dn num2str(d{j}) ','];
end
q{end+1,1}=['{' dn(1:end-1) '}'];
end
end
if isstruct(s)
dims = length(size(s));
if prod(size(s)) > 1
% multidimensional struct: return indices only
for n = 1:prod(size(s))
[d{1:dims}]=ind2sub(size(s),n);
dn=[];
for j=1:dims
dn=[dn num2str(d{j}) ','];
end
q{end+1,1}=['(' dn(1:end-1) ')'];
end
else % scalar struct: return fields
f=fields(s);
for n=1:length(f)
q{end+1,1}=['.' f{n}];
end
end
end
v={};
if ~isempty(q)
for n=1:length(q)
p=getkids(eval(['s' q{n}]),[mn q{n}]);
if ~isempty(p)
for m=1:length(p)
v{end+1,1}=[q{n} p{m}];
end
else
v{end+1,1}=q{n};
end
end
end
q=v;
return