Copy Figure prints the wrong figure

Hello,
I have a script creating a lot of plots. Subsequently they are saved into PowerPoint via code. Therefore I am using
editmenufcn(gcf, 'EditCopyFigure')
and
saveppt2
The problem is, that the script is called from a GUI. So instead of printing the plot to PowerPoint, Matlab prints my GUI.
The function editmenufcn says
% EDITMENUFCN(CMD) invokes edit menu command CMD on figure GCBF.
% EDITMENUFCN(H, CMD) invokes edit menu command CMD on figure H.
So when I pass my opened figure to the function with
editmenufcn(gcf, 'EditCopyFigure')
it should print the figure but it doesn´t. I have tried to pass the current figure with other terms, but still there was no change. When I call the function from command window it works perfectly fine and I am pretty sure, that my GUI is not the problem here.
I even tried to call
graphics.internal.copyFigureHelper(gcf)
but it is still the same problem. Unfortunately I can not look deeper into the copyFigureHelper Function because it is a *.p file.
I know there are other possibilities to print a figure and to save it to Power Point like
print -dmeta
where I can set the resolution and other settings but it doesn´t fulfill my requirements. Because I have a lot of data the plots get fuzzy and I want a transparent background.
Does anyone else have this problem or does anyone know a solution for my problem?
Maybe Matlab is not able to call the callbacks of this figure because they are not visible so it calls the next callback with the same name that is available? But I have no idea how I should change this if this was the problem.
I am using Matlab R2014a.

1 Comment

when I pass my opened figure
somefunction(gcf, ...)
This is where you go wrong. There is absolutely no guarantee that gcf is your opened figure. It's whichever figure is current, so most likely your GUI figure.
See Stephen's answer for the solution.

Sign in to comment.

Answers (2)

Stephen23
Stephen23 on 1 Aug 2016
Edited: Stephen23 on 1 Aug 2016
Do not use gcf. Use the handle of the plots that you created:
fgh = figure(...)
axh = axes(fgh,...)
plot(axh,...)
and pass fgh to whatever functions saves your plots.
Basically you should never use gcf for serious code, such as within callbacks, because doing so will cause exactly the problems that you are experiencing now. The solution is to keep track of all relevant figure and axes handles and use them instead. With practice you will find this quite easy.
gcf should only be used for messing around in the command window, not for any proper code that you intend to use for more than five minutes.

4 Comments

Unfortunately it is still not working. I know I should not use gcf but even when I pass the exact handles, I have the same problem. I use
fig=open([savepath '\Plots\' plotnames{h} '_' num2str(i) '.fig']);
to call my figure, which works perfectly fine. I can configure the figure as I want. Then I pass it to the function saveppt2, which I modified a little to use editmenufcn instead of print -dmeta.
saveppt2(filespec,'figure',fig,'title',plotnames_2{h})
Then saveppt2 gets my figure and renames it:
if isfield(addlParms,'figure')
% Meaning they just put 'Figure', but didn't specify one, default
% behavior for print, just remove the field
if checkParm(addlParms,'figure')
addlParms=rmfield(addlParms,'figure');
else
% More than 4 figures makes it hard to read
if length(addlParms.figure)>4
warning('saveppt2:TooManyFigures','More than 4 figures is not reccomended')
end
end
% Check that the figures actually exist
for i=1:length(addlParms.figure)
try
a=get(addlParms.figure(i));
catch
error('saveppt2:FigureDoesNotExist',['Figure ' addlParms.figure(i) ' does not exist']);
end
end
else
% If no figure is specified, use the current figure.
addlParms.figure=gcf;
end
Afterwards it should copy my figure to the clipboard.
for i=1:fig.count
% For title page only, skip.
if addlParms.figure(i)==0
continue;
end
% Determine what row and column the current figure is on
row=floor((i-1)/addlParms.columns);
column=mod(i-1,addlParms.columns);
% Copy the figure to the clipboard
editmenufcn(['-f' num2str(addlParms.figure(i))], 'EditCopyFigure')
% Paste the contents of the Clipboard:
pic1 = invoke(new_slide.Shapes,'Paste');
end
Using
editmenufcn(['-f' num2str(addlParms.figure(i))], 'EditCopyFigure')
I get the error, that the content from the clipboard could not be pasted. If I simply use
editmenufcn(addlParms.figure(i)], 'EditCopyFigure')
I have the same problem as before, that it prints my GUI and not my figure. Even if I use
editmenufcn(open('C:\exactpath\myfigureiwanttoplot.fig'), 'EditCopyFigure')
it still prints my GUI.
And still if I call the function from command window, it works just as I want.
f=figure;
set(f,'visible','off') % because all my figures are invisible
plot(rand(1,100),rand(1,100))
saveppt2('Test.pptx','figure',f,'title','TEST')
I have no idea what I am doing wrong...
Firstly, replace this line
addlParms.figure=gcf;
with
error('NOT ALLOWED')
Then look at every instance of editmenufcn: this is an undocumented function, so there is no official MATLAB help to tell us how to use it. Use it at your own risk. I would advise you to avoid using undocumented functions.
In any case you call this function in several different ways, which you need to review and check: I suspect that when you call this function with a string input is not valid syntax. Basically, what is
['-f' num2str(addlParms.figure(i))]
supposed to mean ? The descriptions that I have read only show using this function with a figure handle. A string is not a figure handle. You have not provided the function with the figure handle, as my answer told you to do.
As I said, I also tried with
editmenufcn(addlParms.figure(i)], 'EditCopyFigure')
where addlParms.figure(i) should be the figure handle.
I know that the function is undocumented, but it fits my needs the best.
I also created a new GUI to see, whether the problem is in my GUI but I get the same result. I attached the test GUI, so you can see where the problem is.
@Qutijibo: You certainly did not try it with this code:
editmenufcn(addlParms.figure(i)], 'EditCopyFigure')
because that code has an unmatched square bracket, and would immediately give a syntax error. So "As I said, I also tried with" is definitely not true. And it means that you still haven't told us what code you have really used.
In any case there is NO reason to concatenate the figure handle with anything. Perhaps this is the problem ?
The solution is going to be to pass the figure handle. Nothing else.

Sign in to comment.

Guillaume
Guillaume on 2 Aug 2016
In the version of matlab that I'm currently using (2016a), if a string is passed as first argument to editmenufcn, it is assumed to be a command, and the figure used is always gcbf. So you do need to pass a figure handle to editmenufcn as first argument for it to be used.
Also, in the version of matlab I'm using, your test code works fine. The figure pasted in the powerpoint file is the one with the random lines.
I suspect there is a bug in matlab.graphics.internal.copyFigureHelper in your version. As you're not even supposed to use that code there's not much you can do, other than upgrading. As a bonus, in 2016a copyFigureHelper is a m file, so you can see what it's doing.

3 Comments

That is good to know, but unfortunately it does not solve my problem. Can you upload the code from copyFigureHelper? That would be great.
I realise that it does not solve your problem. Unfortunately, since your're using unsupported and undocumented functions, your only avenue is either to rewrite an equivalent or upgrade matlab.
I cannot give you the code for matlab.graphics.internal.copyFigureHelper, it is copyrighted. You could contact MathWorks and ask them for it. Not sure how successful that would be.
matlab.graphics.internal.copyFigureHelper sets various properties of the figure and builds an option list for print, depending on the options set under Preferences -> Figure Copy Template. On my machine, with the preferences I have (never touched that dialogue, so they're default) this is in effect what it does for your test code:
set(hfig, 'InvertHardcopy', 'off');
set(hfig, 'PaperPositionMode', 'auto');
print(hfig, '-clipboard', '-dmeta', '-painters');
On a different machine, with different preferences or graphics card, it may do something else.
Thank you very much. Although there probably is a bug in my Matlab version
set(hfig, 'InvertHardcopy', 'off');
set(hfig, 'PaperPositionMode', 'auto');
print(hfig, '-clipboard', '-dmeta', '-painters');
is exactly what I was searching for. I could not figure out, what the script is doing.
Thanks a lot!

Sign in to comment.

Categories

Find more on Printing and Saving in Help Center and File Exchange

Asked:

on 1 Aug 2016

Commented:

on 3 Aug 2016

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!