FIG files format

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

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. Setting axes tick labels format Matlab plot axes ticks can be customized in a way that will automatically update whenever the tick values change. ...
  2. Reading non-Latin text files A workaround that enables reading non-Latin text files in Matlab is shown...
  3. Plot LimInclude properties The plot objects' XLimInclude, YLimInclude, ZLimInclude, ALimInclude and CLimInclude properties are an important feature, that has both functional and performance implications....
  4. Handle Graphics Behavior HG behaviors are an important aspect of Matlab graphics that enable custom control of handle functionality. ...
  5. Getting default HG property values Matlab has documented how to modify default property values, but not how to get the full list of current defaults. This article explains how to do this. ...
  6. HG2 update HG2 appears to be nearing release. It is now a stable mature system. ...

Categories: Figure window, Handle graphics, Hidden property, Low risk of breaking in future versions, Stock Matlab function, Undocumented feature

Tags: , , ,

Bookmark and SharePrint Print

3 Responses to FIG files format

  1. Jos von Asmuth says:

    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

    • @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 says:

    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

Leave a Reply

Your email address will not be published. Required fields are marked *

*

<pre lang="matlab">
a = magic(3);
sum(a)
</pre>