make saved figures visible on

I perform large batches of simulations, in which I generate a lot of figures and save them as fig. To avoid, that these figures pop up and make any further work on the machine impossible, I generate these plots in invisible figures. Then i save them as .fig files. This action conserves the property invisible, so that a loading of such a figure only leads to a visible figure, after doing a set(gcf,'visible','on')
I tried to set the state of the visibility in the file on the disk by using the following function:
function makevisible(file)
f=load(file,'-mat');
n=fieldnames(f);
f.(n{1}).properties.Visible='on'; % this line does not have much effect in 16b, used to be the key line in earlier versions.
f.(n{2}).GraphicsObjects.Format3Data.Visible='on';
save(file,'-struct','f')
end
sadly the command: f=load(file,'-mat'); does not only load the data into the workspace struct f, but also generates a figure. This figure then becomes visible, when changing the state. I tried to delete this figure with
close gcf
even before I set the visibility. But this does not only delete the figure, but also alters the data in f. after the close gcf command f is the struct of a "having been deleted figure".
How can I achieve to have saved figure files with visible on, without having every one of these figures to pop up on the screen. ???
My Solution
Its not exactly what I originally wanted, as it still saves the figures invisible. But it solves the described problem by defining a create function, which sets the visibility to on during creation.
function makevisible(file)
top =load(file,'-mat' ,'hgM_070000' );
top.hgM_070000.GraphicsObjects.Format3Data.CreateFcn = 'set(gcf,''visible'',''on'')'
save(file,'-struct','top','-append')
end

8 Comments

Are these figures to be loaded by other people using Matlab? If not (or even if they are) then I would suggest just writing a simple wrapper function for loading a figure which sets its 'Visible' property to 'on' and then you just call your function instead of a call to the raw figure loading.
This figures are intended (not all of them, but some interesting cases) to also be sent to third party matlab users. And then, of course, I always get the reply: "There seems to be something wrong with your figures. They seem to load, there is no error message, but nothing does show up. -- Strange " That's exactly the situation I want to avoid.
Can it really be, that it is just impossible, to save a normal (visible) figure, without having it poping up on the screen?
I never save figures so I'm not too familiar with how they save and what you can manipulate. I always save data and recreate the figure from that when I need.
Can't you ship the wrapper loading function to them with the figures? I tried a few attempts at doing this, but it seems the figure is just literally saved exactly as you see it and loading it as a Mat file and setting it to 'Visible' will make it visible for you too. IT would be the same problem if you did the other 'invisibility' trick of creating the figure off-screen because then it would also be off-screen when loaded.
I GOT IT:
Its not exactly what I originally wanted, as it still saves the figures invisible. But it solves the described problem by defining a create function, which sets the visibility to on during creation.
function makevisible(file)
top =load(file,'-mat' ,'hgM_070000' );
top.hgM_070000.GraphicsObjects.Format3Data.CreateFcn = 'set(gcf,''visible'',''on'')'
save(file,'-struct','top','-append')
end
Questions: Can anybody give an estimation, on how durable this solution is? I have no clue, where this strange variable name hgM_070000 does come from. Will this variable name change with every Matlab Version?
Since that is your solution why not just do it when you first create the figure (or before you save it), then you don't need to load the file as a .mat and manipulate that structure at all. This solution won't suddenly cause it to appear visible on your screen like others would.
This is a good Idea. Thean I also dont have to care about this hgM_070000 variable name. It is just a
ha.CreateFcn = 'set(gcf,''visible'',''on'')';
Jan
Jan on 17 Dec 2016
Edited: Jan on 17 Dec 2016
Creating callbacks as strings remains dangerous: As soon as a customer has redefined "gcf" in the command window, opening you fig files will produce strange and confusing results.
In older Matlab versions LOAD of a fig file did not open the figure. That this is the case now is rather confusing and impractical.

Sign in to comment.

 Accepted Answer

I repost here the solution, I posted myself in the comments before, in order to be able to "accept" an Anwer:
Its not exactly what I originally wanted, as it still saves the figures invisible. But it solves the described problem by defining a create function, which sets the visibility to on during creation. (Strangely, this procedure was not possible in R2012b where I tried this first. I guess it works since the large figure changes in R2014b(?) )
function makevisible(file)
top =load(file,'-mat' ,'hgM_070000' );
top.hgM_070000.GraphicsObjects.Format3Data.CreateFcn = 'set(gcf,''visible'',''on'')'
save(file,'-struct','top','-append')
end
This works, but I felt unconfortable about the strange hgM_070000 variable, which has to be used.
Adam then brought up the Idea to make this step directly in the saving application and not as a rework step after saving the file.
This is of course a good Idea. It makes the execution faster, and the fiddling around with this mysterious hgM_070000 Variable falls away.
ha.CreateFcn = 'set(gcf,''visible'',''on'')';
Jan still sees some difficulties in this Method, as gcf might be redefined in the matlab Workspace or path, where the figure is beeing opened.
True, but the unexperienced user will just doubleclick the fig file, and his (perhaps never before used) Matlab installation starts. Little chance of having redefined gcf. And the experienced user should know, that he should not do things like this, or he would know how to deal with the error message.

2 Comments

You can be a little more robust by using gcbo rather than gcf as this is explicitly the handle to the object whose callback is currently executing rather than just the current figure. This function handle approach for the CreateFcn appears to work after a quick test:
@(src,evt)set(gcbo,'visible','on')
Awesome solution Adam, thank you, this works like a charm on R2018b and R2019a.

Sign in to comment.

More Answers (2)

Jan
Jan on 16 Dec 2016
Are you really sure, that f=load(file,'-mat') opens the figure? This would be very strange.
Is it required to set "f.(n{2}).GraphicsObjects.Format3Data.Visible='on'"? Which Matlab version are you using?
A simply solution would to insert the code to enable the visibility during the loading of the figure.

2 Comments

Heinz
Heinz on 16 Dec 2016
Edited: Heinz on 16 Dec 2016
<< Are you really sure, that f=load(file,'-mat') opens the figure?
By "open" I meant that it does the same thing as e.g. uiopen. The complete figure is becoming operative. But additionally to uiopen, I also get the variable f generated. But it would just be enough to get the dead data set of the figure. You can test these simple lines:
test = figure('visible','off')
plot([1 10 100],[1 2 3])
saveas(gcf, 'test.fig')
close all
vorher = load('test.fig','-mat');
set(gcf,'visible','on')
At least it is very unconvinient to not beeing able to set the visibility.
See my comment above to understand why writing a special opening routine is not useful. Of cource I have done this for myself a long time ago.
I use 16b.
When loading the figure file as a struct opens the figure already, this figure must contain any code, which triggers the displaying. What a pitty. This seems to be a perfect example for the bad idea to mix code and data. Blame Mathworks.
Then you could go the hard way: Create the figures invisible at first. Then open all fig files, set the visibility and save the fig fiels again. Although this pollutes your screen, it will do this for a short period of time only.
In older Matlab versions the conversion from a figure to code worked: http://www.mathworks.com/matlabcentral/fileexchange/20152-guidegetter . I'm not sure, if this could be useful for your case.

Sign in to comment.

Steven Lord
Steven Lord on 16 Dec 2016
Would using a command to open the figure that forces it to be visible satisfy your needs? If so use the openfig function with the 'visible' value for the visibility input argument as per the second example on that documentation page.

1 Comment

Heinz
Heinz on 19 Dec 2016
Edited: Heinz on 19 Dec 2016
These figures are intended (not all of them, but some interesting cases) to also be sent to third party matlab users. And then, of course, I always get the reply: "There seems to be something wrong with your figures. They seem to load, at least there is no error message, but nothing does show up. -- Strange " That's exactly the situation I want to avoid.
Yes I could setup a complete ecosystem. But this is then much more complex for the 3rd party user (who perhaps only uses matlab once a month) to install some opener m-files. (where to install, how to set a path, is it dangerous, ...)
Just clicking the fig file in the mail browser is soooooooo much more convienient. !!!

Sign in to comment.

Categories

Find more on Creating, Deleting, and Querying Graphics Objects in Help Center and File Exchange

Products

Asked:

on 16 Dec 2016

Commented:

on 23 Oct 2019

Community Treasure Hunt

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

Start Hunting!