Undocumented Matlab
  • SERVICES
    • Consulting
    • Development
    • Training
    • Gallery
    • Testimonials
  • PRODUCTS
    • IQML: IQFeed-Matlab connector
    • IB-Matlab: InteractiveBrokers-Matlab connector
    • EODML: EODHistoricalData-Matlab connector
    • Webinars
  • BOOKS
    • Secrets of MATLAB-Java Programming
    • Accelerating MATLAB Performance
    • MATLAB Succinctly
  • ARTICLES
  • ABOUT
    • Policies
  • CONTACT
  • SERVICES
    • Consulting
    • Development
    • Training
    • Gallery
    • Testimonials
  • PRODUCTS
    • IQML: IQFeed-Matlab connector
    • IB-Matlab: InteractiveBrokers-Matlab connector
    • EODML: EODHistoricalData-Matlab connector
    • Webinars
  • BOOKS
    • Secrets of MATLAB-Java Programming
    • Accelerating MATLAB Performance
    • MATLAB Succinctly
  • ARTICLES
  • ABOUT
    • Policies
  • CONTACT

FIG files format

December 22, 2010 18 Comments

A short while ago, a StackOverflow user asked how to extract data from FIG files in Matlab. The answer to this question is easy, but I wish to use the opportunity to show how this can be useful in Matlab applications.

The need: load a FIG without displaying it

In data-processing applications, we often present data in graphs that can then be manipulated and saved for later use. In Matlab, saving is done interactively (via the figure’s File/Save menu option or via the figure’s Save toolbar button), or programmatically (via the hgsave function). In all cases, the data is stored in a *.FIG file (the FIG extension can actually be changed, but I really don’t see why).
The point is that in order to re-load the stored data, we need to use hgload, which has a nasty side-effect of actually displaying the stored figure.
This is bad in terms of performance and memory, especially for heavily-laden GUI figures, not to mention the fact that sometimes we do not want to display the GUI at all. We often just need to extract a sub-set of the stored information (for example, the plot values), without having to display the figure.

The answer: FIGs are simply MATs in disguise

Here’s where the undocumented stuff enters:
It seems that a FIG file is simply a hierarchical structure of all the non-default properties of the stored figure and its descendant handles, all this stored within a simple MAT file.
This is hinted in several places, for example in hgsave‘s doc page, and in the MAT-file preferences panel:

MAT-file preferences (note the FIG clarification)
MAT-file preferences (note the FIG clarification)

Knowing this, we can easily load the data, without displaying the figure, by using load(filename,’-mat’) rather than hgload. For example:

% Create and store a simple plot figure
>> figure('Name','Test #1');
>> plot(1:9, sqrt(1:9));
>> hgsave(gcf,'testFig');
% Load the figure data
>> d = load('testFig.fig','-mat')
d =
    hgS_070000: [1x1 struct]   % a Matlab 7 figure
% Investigate the figure data
>> d.hgS_070000
ans =
          type: 'figure'
        handle: 1
    properties: [1x1 struct]
      children: [1x1 struct]
       special: []
>> d.hgS_070000.children
ans =
          type: 'axes'
        handle: 176.08251953125
    properties: [1x1 struct]
      children: [1x1 struct]
       special: [4x1 double]
>> d.hgS_070000.children.children
ans =
          type: 'graph2d.lineseries'
        handle: 177.0830078125
    properties: [1x1 struct]
      children: []
       special: []
>> d.hgS_070000.children.children.properties
ans =
              Color: [0 0 1]
              XData: [1 2 3 4 5 6 7 8 9]
              YData: [1 1.4142 1.7321 2 2.2361 2.4495 2.6458 2.8284 3]
    ApplicationData: [1x1 struct]
        XDataJitter: 0
          XDataMode: 'manual'
      ObeyXDataMode: 'auto'
                ...
% Extract plot data
>> YData = d.hgS_070000.children.children.properties.YData
YData =
  1.0000  1.4142  1.7321  2.0000  2.2361  2.4495  2.6458  2.8284  3.0000

% Create and store a simple plot figure >> figure('Name','Test #1'); >> plot(1:9, sqrt(1:9)); >> hgsave(gcf,'testFig'); % Load the figure data >> d = load('testFig.fig','-mat') d = hgS_070000: [1x1 struct] % a Matlab 7 figure % Investigate the figure data >> d.hgS_070000 ans = type: 'figure' handle: 1 properties: [1x1 struct] children: [1x1 struct] special: [] >> d.hgS_070000.children ans = type: 'axes' handle: 176.08251953125 properties: [1x1 struct] children: [1x1 struct] special: [4x1 double] >> d.hgS_070000.children.children ans = type: 'graph2d.lineseries' handle: 177.0830078125 properties: [1x1 struct] children: [] special: [] >> d.hgS_070000.children.children.properties ans = Color: [0 0 1] XData: [1 2 3 4 5 6 7 8 9] YData: [1 1.4142 1.7321 2 2.2361 2.4495 2.6458 2.8284 3] ApplicationData: [1x1 struct] XDataJitter: 0 XDataMode: 'manual' ObeyXDataMode: 'auto' ... % Extract plot data >> YData = d.hgS_070000.children.children.properties.YData YData = 1.0000 1.4142 1.7321 2.0000 2.2361 2.4495 2.6458 2.8284 3.0000

We see a couple of interesting things in this simple example:
First, note that the top-level structure node is called “hgS_070000” – we’ll dig into this next week. Basically, it indicates that the structure holds a Matlab 7 figure.
Secondly, we see hidden/undocumented properties of the stored objects (for example, the lineseries’ XDataJitter and ObeyXDataMode properties). ApplicationData is such a hidden handle, which is widely used as a substitute for any handle’s UserData property (the built-in setappdata and getappdata functions are simply wrappers for accessing this property using standard set and get functions).
Have you used the FIG/MAT feature for any useful functionality? If so, please do share your experience in a comment.
Next week, I will explain how looking under hgsave‘s hood leads to useful functions and to an interesting insight about Matlab’s future. Merry Christmas everybody!

Related posts:

  1. Reading non-Latin text files – A workaround that enables reading non-Latin text files in Matlab is shown...
  2. AppDesigner's mlapp file format – MLAPP files created by AppDesigner can be inspected and manipulated outside AppDesigner. ...
  3. Setting axes tick labels format – Matlab plot axes ticks can be customized in a way that will automatically update whenever the tick values change. ...
  4. Bar plot customizations – Matlab bar charts can be customized in various nifty ways. ...
  5. Accessing plot brushed data – Plot data brushing can be accessed programmatically using very simple pure-Matlab code...
  6. Using linkaxes vs. linkprop – linkaxes has a built-in limitation, so using linkprop may sometimes be beneficial. ...
Handle graphics Hidden property Pure Matlab Undocumented feature
Print Print
« Previous
Next »
18 Responses
  1. Jos von Asmuth December 23, 2010 at 07:55 Reply

    Hi Yair,

    Thanks again. Perhaps it is a simple issue, but do you happen to know how to, once loaded, create a gui or figure out of such a structure? It could be helpfull for automaticcally generating GUI’s.

    Kind regards,
    Jos

    • Yair Altman December 23, 2010 at 10:51 Reply

      @Jos – You can use the struct2handle function for this. I will explain its usage next week. Of course, you can always use hgload on the original FIG filename.

  2. Volkmar Glauche December 25, 2010 at 00:02 Reply

    I am using this feature to “repair” GUI figures created with some versions of guide. Some versions of guide store callbacks as function handles in a way that is not compatible with all versions of MATLAB I have to work with (R14SP3 onwards). I parse the function handles and replace them with a callback string (if possible).
    Also, in conjunction with gencode this is useful to read and modify the MATLAB code of a saved figure.

    Best,

    Volkmar

  3. Robin Lundberg December 17, 2014 at 08:29 Reply

    Trying this in matlab 2014b still opens the gui (sometimes).
    When you load a gui you get

    >>figData = load('guiPostProcessing.fig', '-mat')
    figData = 
        hgS_070000: [1x1 struct]
        hgM_070000: [1x1 struct]

    >>figData = load('guiPostProcessing.fig', '-mat') figData = hgS_070000: [1x1 struct] hgM_070000: [1x1 struct]

    And this might open the figure. To prevent this I did this instead and it seems to work fine

    >> figData = load('guiPostProcessing.fig', '-mat', 'hgS_070000')
    figData = 
        hgS_070000: [1x1 struct]

    >> figData = load('guiPostProcessing.fig', '-mat', 'hgS_070000') figData = hgS_070000: [1x1 struct]

  4. Mariam July 27, 2015 at 23:13 Reply

    Hi,

    I have used above following command to load the attributes of figures

    d = load('testFig.fig','-mat')

    d = load('testFig.fig','-mat')

    and then changed those attributes. I want to know how could I apply new attributes to my figure or how can I save variable ‘d’ into .fig format. Please reply.

    Regards,
    Mariam

    • Yair Altman July 28, 2015 at 01:07 Reply

      @Mariam – you can simply use the save command to save your modified d struct back into the *.fig file, and then open this FIG file normally:

      save('testFig.fig','d','-mat'); % save modified d struct
      testFig; % open figure

      save('testFig.fig','d','-mat'); % save modified d struct testFig; % open figure

      • Mariam July 28, 2015 at 05:19

        I already tried this and this the error I am getting

        >> save('C:UsersMariamDesktopfitted responseatlas masksIPS_1.fig','s','-mat')
        >> open('C:UsersMariamDesktopfitted responseatlas masksIPS_1.fig')
        ??? Error using ==> open at 163
        Invalid Figure file format

        >> save('C:UsersMariamDesktopfitted responseatlas masksIPS_1.fig','s','-mat') >> open('C:UsersMariamDesktopfitted responseatlas masksIPS_1.fig') ??? Error using ==> open at 163 Invalid Figure file format

      • Yair Altman July 28, 2015 at 05:23

        @Mariam – You probably updated your s data-struct incorrectly

      • Mariam July 28, 2015 at 20:53

        I tried it without making any changes to ‘s’. Just loading it

        s = load('C:UsersMariamDesktopfitted responseatlas masksIPS.fig','-mat');

        s = load('C:UsersMariamDesktopfitted responseatlas masksIPS.fig','-mat');

        and re-saving it

        save('testFig.fig','s','-mat'); % save modified d struct

        save('testFig.fig','s','-mat'); % save modified d struct

        However the effect remains it

        open('testFig.fig')
        ??? Error using ==> open at 163
        Invalid Figure file format.

        open('testFig.fig') ??? Error using ==> open at 163 Invalid Figure file format.

      • Yair Altman July 29, 2015 at 01:12

        @Mariam – the save command save the data including the variable name as top-level struct field. You should keep the same top-level field-name as used by the FIG format (hgS_070000 or hgM_070000):

        s = load('IPS.fig','-mat');
        hgS_070000 = s.hgS_070000;
         
        % modify hgS_070000
         
        save('IPS.fig','hgS_070000','-mat');

        s = load('IPS.fig','-mat'); hgS_070000 = s.hgS_070000; % modify hgS_070000 save('IPS.fig','hgS_070000','-mat');

    • Martin July 29, 2015 at 03:53 Reply

      @Mariam – you can also use the -struct flag of the save function, if you want to modify the struct s directly without going through another temporary variable:

      save('testFig.fig', '-struct', 's', '-mat');

      save('testFig.fig', '-struct', 's', '-mat');

      That way the field names of the struct s are treated as the variable names to be saved to the file.

  5. Lo que he aprendido: exportar todas las imágenes fig de una carpeta a pdf con Matlab | Onda Hostil April 14, 2016 at 16:48 Reply

    […] Relación entre figuras y archivos mat […]

  6. Varshini Guddanti June 16, 2016 at 04:54 Reply

    Can the ‘load’ method convert the figure into a matrix to do some operations later?

    • Yair Altman June 16, 2016 at 09:32 Reply

      @Varshini – load() simply returns a Matlab struct. You can then process and convert this struct in your Matlab code in whichever way that you wish.

  7. ElGalloGringo July 21, 2016 at 20:18 Reply

    I am trying to write my own script to parse this struct data and generate a figure from a subset of the children handles. One weird thing I am running into is that even though in the struct from the FIG file the title, xlabel, and ylabel show up as children of the axes, when the FIG file is loaded with openfig, those children handles get assigned to the ‘title’, ‘xlabel’, and ‘ylabel’ properties of the axes. I can’t figure out how Matlab is determining that these children handles are special and shouldn’t just be added as children.

    Any thoughts?

    • Malcolm Lidierth July 24, 2016 at 00:24 Reply

      Not sure why you think it should not. Any MATLAB OOP class can define custom saveobj and loadobj methods to deal with the serialisation/deserialization process.

      Not your question but maybe relevant to what you are doing: an undocumented (I think) feature of MATLAB is that constructors will accept a structure on input. So

      s.Name='This is my figure';
      h=figure(s);

      s.Name='This is my figure'; h=figure(s);

      will give you a figure with the specified Name and other properties set to their default values. All HG objects seem to comply with this. Add properties as required to s.

  8. E. LeFort June 5, 2017 at 19:00 Reply

    Hello, great post. I want to share an issue and hopefully receive some help in defining the solution. Fist I derived a plot using the risetime function in matlab. This plot contains all types of information I would like to extract. Specifically the upper cross time which is marked with a red “x” by default.

    I performed the following code:

    fig.hgS_070000.children.children.properties

    fig.hgS_070000.children.children.properties

    However, when ran I received the following error:

    "Expected one output from a curly brace or dot indexing expression, but there were 2 results."

    "Expected one output from a curly brace or dot indexing expression, but there were 2 results."

    Is there a way to access this curly brace Information? I suspect this is an indexing issue however I have no idea how to access it.

    Any help is greatly appreciated.

    • Yair Altman June 5, 2017 at 19:08 Reply

      There are probably multiple children, so accessing children.children and/or children.properties results in an understandable error. You can try to access individual children using indexing, for example: fig.hgS_070000.children(1).children(1).properties

Leave a Reply
HTML tags such as <b> or <i> are accepted.
Wrap code fragments inside <pre lang="matlab"> tags, like this:
<pre lang="matlab">
a = magic(3);
disp(sum(a))
</pre>
I reserve the right to edit/delete comments (read the site policies).
Not all comments will be answered. You can always email me (altmany at gmail) for private consulting.

Click here to cancel reply.

Useful links
  •  Email Yair Altman
  •  Subscribe to new posts (feed)
  •  Subscribe to new posts (reader)
  •  Subscribe to comments (feed)
 
Accelerating MATLAB Performance book
Recent Posts

Speeding-up builtin Matlab functions – part 3

Improving graphics interactivity

Interesting Matlab puzzle – analysis

Interesting Matlab puzzle

Undocumented plot marker types

Matlab toolstrip – part 9 (popup figures)

Matlab toolstrip – part 8 (galleries)

Matlab toolstrip – part 7 (selection controls)

Matlab toolstrip – part 6 (complex controls)

Matlab toolstrip – part 5 (icons)

Matlab toolstrip – part 4 (control customization)

Reverting axes controls in figure toolbar

Matlab toolstrip – part 3 (basic customization)

Matlab toolstrip – part 2 (ToolGroup App)

Matlab toolstrip – part 1

Categories
  • Desktop (45)
  • Figure window (59)
  • Guest bloggers (65)
  • GUI (165)
  • Handle graphics (84)
  • Hidden property (42)
  • Icons (15)
  • Java (174)
  • Listeners (22)
  • Memory (16)
  • Mex (13)
  • Presumed future risk (394)
    • High risk of breaking in future versions (100)
    • Low risk of breaking in future versions (160)
    • Medium risk of breaking in future versions (136)
  • Public presentation (6)
  • Semi-documented feature (10)
  • Semi-documented function (35)
  • Stock Matlab function (140)
  • Toolbox (10)
  • UI controls (52)
  • Uncategorized (13)
  • Undocumented feature (217)
  • Undocumented function (37)
Tags
AppDesigner (9) Callbacks (31) Compiler (10) Desktop (38) Donn Shull (10) Editor (8) Figure (19) FindJObj (27) GUI (141) GUIDE (8) Handle graphics (78) HG2 (34) Hidden property (51) HTML (26) Icons (9) Internal component (39) Java (178) JavaFrame (20) JIDE (19) JMI (8) Listener (17) Malcolm Lidierth (8) MCOS (11) Memory (13) Menubar (9) Mex (14) Optical illusion (11) Performance (78) Profiler (9) Pure Matlab (187) schema (7) schema.class (8) schema.prop (18) Semi-documented feature (6) Semi-documented function (33) Toolbar (14) Toolstrip (13) uicontrol (37) uifigure (8) UIInspect (12) uitable (6) uitools (20) Undocumented feature (187) Undocumented function (37) Undocumented property (20)
Recent Comments
Contact us
Captcha image for Custom Contact Forms plugin. You must type the numbers shown in the image
Undocumented Matlab © 2009 - Yair Altman
This website and Octahedron Ltd. are not affiliated with The MathWorks Inc.; MATLAB® is a registered trademark of The MathWorks Inc.
Scroll to top