Archive for the ‘Handle graphics’ Category

uitree

Wednesday, August 11th, 2010

Can you guess which built-in Matlab function is the top search-term on UndocumentedMatlab.com and yet one of the least discussed topic on the CSSM forum?

The answer is uitree – Matlab’s built-in function for displaying data in a hierarchical (tree) GUI component. uitree has been included in all Matlab 7 releases, but has never been officially supported. Like most other uitools in the %matlabroot%/toolbox/matlab/uitools/ folder, uitree and its companion uitreenode are semi-documented, meaning that they have no support or doc-page, but do have readable help sections within their m-files. In our case, edit the uitree.m and uitreenode.m files to see their help section.

Note the following comment within %matlabroot%/toolbox/local/hgrc.m, which implies that uitree may soon become fully supported, although its interface might change somewhat (as was the case when uitable became supported in R2008a):
Temporarily turn off old uitree and uitreenode deprecated function warning… When we introduce the new documented uitree to replace the old undocumented uitree …

Like most other uitools (e.g. uitable and uitab), uitree is based on an underlying Java component, which ultimately extends Swing’s standard JTree. uitree sets up a scrollable JTree on-screen without the hassle of setting up a scrollable viewport and other similar nuts and bolts. In fact, you don’t need to know any Java to use uitree (although knowing JTree can greatly help you customize it) – uitrees can be manipulated using pure Matlab code, as shall be seen below.

uitree accepts an optional figure handle followed by P-V (property-value) pairs. Settable properties are Root, ExpandFcn, SelectionChangeFcn, Position (also Parent, but read on). As in uitab, a ‘v0′ input argument may be necessary to suppress a warning message. Note that uitrees are always created as a direct child of the containing figure, ignoring creation-time Parent values. However, the Parent property can be modified following the tree’s creation:

[mtree, container] = uitree('v0', 'Root','C:\', 'Parent',hPanel); % Parent is ignored
set(container, 'Parent', hPanel);  % fix the uitree Parent

A simple uitree

A simple uitree

uitree returns two arguments: a handle to the created tree (a Java object wrapped within a Matlab handle) and an entirely-undocumented second optional argument holding a handle to the Matlab GUI container of the created tree. These two arguments are exactly the two arguments returned from the javacomponent function that I described last week.

uitreenode

uitree automatically understands Root objects of type Handle Graphics, Simulink model or char string (interpreted as a file-system folder name). Other Root types require setting dedicated ExpandFcn, SelectionChangeFcn Matlab callbacks (see uitree’s help section or below for examples).

If we need to create a custom tree hierarchy (i.e., our root node is not an HG object, Simulink model or folder name), then we need to use the semi-documented uitreenode function as follows:

node = uitreenode('v0',handle(mtree),'my root','c:\root.gif',false);
mtree.setRoot(node);
set(mtree,'Root',node);  % alternative to mtree.setRoot()

uitreenode accepts 4 arguments: a string or handle value (the node’s “internal” value), a string description (shown next to the node’s icon), an icon filename ([] will result in an icon assigned based on the node value), and a flag indicating whether the node is a leaf (no children) or not.

uitreenode returns a node object, which is little more than a Matlab handle wrapper for a Java Swing DefaultMutableTreeNode.

Node manipulation

Nodes can be added, moved or removed by node methods: node.add(anotherNode) adds anotherNode to the end of this node’s children list (possibly detaching it from its previous parent); node.insert(anotherNode,index) does the same but inserts anotherNode at a specific child index, rather than at the end; node.clone() makes a duplicate of this node that can then be added to another node; node.remove(index) and node.remove(node) remove a specific node whereas node.removeFromParent() removes this node; node.removeAllChildren() removes all children, if any, of this node.

Nodes can also be added and removed at the tree level: mtree.add(parent,nodes) allows adding a list of nodes to a parent node and mtree.remove(nodes) removes the specified nodes.

In order to programmatically collapse and expand nodes, use mtree.collapse(node) and mtree.expand(node).

Nodes can be programmatically selected using mtree.setSelectedNode(node). Multiple nodes may be selected using mtree.setSelectedNodes, if an earlier call to mtree.setMultipleSelectionEnabled(true) was made (default is multiple-selection disabled):

mtree.setSelectedNode(root);  % root is a node
mtree.setSelectedNodes([root,node1,node2]);  % select 3 nodes

programmatically selecting multiple tree nodes

programmatically selecting multiple tree nodes

The currently-selected node(s) can be accessed using mtree.getSelectedNodes. Node selection callbacks often require knowledge of the currently selected rows:

% Tree set up
mtree = uitree(..., 'SelectionChangeFcn',@mySelectFcn);
set(mtree, 'SelectionChangeFcn',@mySelectFcn); % an alternative
 
% The tree-node selection callback
function nodes = mySelectFcn(tree, value)
    selectedNodes = tree.getSelectedNodes;
    if ~isempty(selectedNodes)
        % ...
    end
end  % mySelectFcn

Interested readers might also benefit from looking at the tree manipulations that I have programmed in my FindJObj utility.

Next week’s article will show how uitrees can be customized. There are numerous possible customizations, including icons, labels, appearance, and behavior. So if you have any special request, please post a comment below.

The javacomponent function

Wednesday, August 4th, 2010

In this blog I have often showed how using Java components can significantly improve Matlab GUI. Here is a simple reminder:

sample Java components integrated in Matlab figure window (click for details)

sample Java components integrated in Matlab figure window (click for details)

Matlab is highly integrated with Java, and Java classes can seamlessly be accessed from Matlab. However, displaying Java GUI objects, as opposed to using computational (non-displayable) Java classes, requires using Matlab’s built-in javacomponent function. I have often used this function in past articles here, and today I would like to describe it in more detail.

javacomponent, available since R14 (Matlab 7.0), is yet another semi-documented built-in function. This means that the function is explained in a comment within the function (which can be seen via the edit(‘javacomponent’) command), but nonetheless does not have official help or doc pages. It is an unsupported function originally intended only for internal Matlab use (which of course doesn’t mean we can’t use it).

javacomponent accepts a component class name (a string) or a reference to a previously-created component object, an optional pixel position parameter (default=[20,20,60,20], just like uicontrol; may also contain the strings ‘North’, ‘South’, ‘East’ or ‘West’), and an optional parent container handle (defaults to the current figure). javacomponent then adds the requested component as a child of the requested parent container and wraps it in a Matlab Handle-Graphics (HG) container. javacomponent returns two handles: the Matlab HG container handle and a reference (handle) to the Java component. Here are some sample invocation formats:

>> [jButton, hButton] = javacomponent('javax.swing.JButton')
hButton =
	javahandle_withcallbacks.javax.swing.JButton
jButton =
          158.002197265625
 
>> javacomponent('javax.swing.JButton','North');
>> javacomponent(javax.swing.JButton('Click me!'),[50,40,80,30]);
>> javacomponent(javax.swing.JButton('Click me!'),'East',hFig);

Note the difference between Java object creation and javacomponent: A pre-created Java object only resides in JVM (Java Virtual Machine) memory, not onscreen, until javacomponent is called to display it. javacomponent only creates objects when a class name (string) parameter is passed to it, as a convenience service to programmers. In practice, it is better to separate these two actions: create the Java object separately, and then pass the object’s reference handle to javacomponent for display. This enables easier error-trapping if the Java object cannot be created or fails to initialize, before attempting to display the object:

% Create and initialize a JScrollBar object
try
   jScrollbar = javaObjectEDT('javax.swing.JScrollBar');
   jScrollbar.setOrientation(jScrollbar.HORIZONTAL);
catch
   error('Cannot create Java-based scroll-bar!');
end
% Display the object onscreen
try
   javacomponent(jScrollbar,'South');
catch
   error('Cannot display Java-base scroll-bar!');
end

Note that Java GUI object should always use the EDT (Event Dispatch Thread). The reasons for this were outlined in the recent Matlab-EDT article. For this reason, the JScrollBar is created using the built-in javaObjectEDT function, which exists since R2008a and became documented/supported in R2009a.

javacomponent accepts parent handles that are figures, toolbars, uipanels or uicontainers. Unfortunately, frames are not uicontainers and therefore cannot be used as javacomponent parents. Addendum Aug 6 2010: I made an incorrect statement in the original post here regarding uipanels, which has now been removed. I thank the reader who pointed this out to me.

Once the component has been created, even before it has been placed onscreen, it can be manipulated just like any other Java object. For example:

jButton.setText('Click again!');  % or: set(jButton,'text','…')

The component can also be manipulated to some extent via its HG container, which is of a special Matlab type (class) called hgjavacomponent. This includes getting/setting the component position, position units, visibility, resizing callback, tag, UserData etc:

set(hButton,'units','norm', 'position',[0.2,0.3,0.1,0.05]);
set(hButton,'visible','off'); %note: on/off, not true/false as in Java
set(hButton,'ResizeFcn',{@resizeCallbackFunc,param1,param2});

When adding Java components which are container classes (descendants of java.awt.Container), it is important to remember that only other Java components can be added to these containers. Matlab objects such as axes (for plots or images) and uicontrols cannot be added since they do not have a Container wrapper. Therefore, feel free to use these Java containers as long as their contained GUI is limited to Java components (JButton, JComboBox etc.). This limitation is very annoying – it would be very useful to be able to place Matlab axes or uicontrols within a JTabbedPane or JSplitPane. Instead, we need to rely on Matlab-based workarounds (uitab and uisplitpane) which are cumbersome compared to their Java counterparts.

javacomponent can be used to place not only Swing components but also Swing-extended components onscreen. Matlab itself almost never uses Swing components as-is, instead preferring to use MathWorks-derived extensions of these components, generally in the com.mathworks.mwswing or com.mathworks.widgets packages. These packages and their classes are all in the static Java classpath and are therefore automatically available for use by Matlab programmers.

Just like Matlab components, javacomponent can also display third-party or your own Swing-derived components. There are quite a few online sources for Swing components that can easily be incorporated in your Matlab application. Simply download the relevant class files, add them to your static (via classpath.txt) or dynamic (via javaaddpath) Java classpath, use javacomponent to display them, then use their reference handle to manipulate their appearance and behavior.

javacomponent, useful as it is, has several limitations. In its string variant (classname) it requires a fully-qualified classname that is not inferred automatically. It also has a different parameters format than uicontrol, which may confuse users. javacomponent also cannot display java.awt.Window components. Finally, it returns two handles – one is a handle() reference of the Java object; the second an HG handle (a double numeric value) of the automatically-created HG container – users are often confused as to which property should be set on which of these handles.

To overcome these limitations, I created UIComponent – a utility that merges uicontrol and javacomponent, available for download on the File Exchange. It accepts all uicontrol parameters and styles, as well as any other displayable Java (Swing/AWT) class. uicontrol’s calling syntax was preserved for full backwards compatibility. uicomponent uses the built-in uicontrol whenever possible (for standard Matlab styles), and javacomponent for all other Java classes.

uicomponent returns the same two handles that javacomponent returns (namely, a Java reference handle and a numeric HG handle), modified to include each other’s properties and handles (yet another undocumented trick that merits a dedicated article). Here are some examples (more can be found in uicomponent’s help comment):

uicomponent('style','edit', 'String','hello');  % a regular uicontrol
uicomponent(hFig, 'style','edit', 'String','hello'); % specify parent
uicomponent('style','jspinner','value',7);
uicomponent('style','javax.swing.jslider','tag','myObj'); 
uicomponent('style','JComboBox',{1,pi,'text'},'editable',true);

Another File Exchange submission which aims to tackle some of javacomponent’s limitations is Malcolm Lidierth’s JCONTROL. jcontrol uses Matlab’s new object-oriented class approach and has the benefit of returning just a single handle object, which aggregates the handles for both HG container and the contained Java object.

Tab panels – uitab and relatives

Wednesday, June 23rd, 2010

In the past year, readers of this blog have used its search box thousands of times. Can you guess what the top search terms are?

It turns out that 7 of the top 15 search terms relate to tables, trees and tab-panes.

These items are related in being standard GUI elements that unfortunately have very lacking support in Matlab. They all have corresponding functions in the %matlabroot%/toolbox/matlab/uitools folder, which was already introduced here as containing many unsupported GUI functions. Specifically, uitable for tables (this became supported in R2008a, but even the supported version has many important undocumented aspects); uitree and uitreenode for trees; and uitab and uitabgroup for tab-panes, which are today’s subject. Future articles will describe tables, trees and tab-panes in more detail.

uitab & uitabgroup

Like most other uitools, the uitab and uitabgroup functions are semi-documented, meaning that they have no support or doc-page, but do have readable help sections within their m-files. In our case, edit the uitab.m and uitabgroup.m files to see their help section.

Available since 2004 (R14 SP2, aka 7.0.4), Matlab’s uitabgroup uses the Matlab Java widget com.mathworks.hg.peer.UITabGroupPeer, which extends the standard javax.swing.JTabbedPane. Unlike uitable and uitree, which use actual Java objects to both store and present the data, uitabgroup only sets up the Java object to display the tabs, whereas the tab contents themselves are placed in entirely unrelated Matlab uicontainers. Matlab uses very clever double-booking to keep the Java and Matlab objects synchronized. The ability to “switch” tabs is actually a deception: in reality, a listener placed on the SelectedIndex property of the tab group causes the relevant Matlab container to display and all the rest to become hidden. Other listeners control containers’ position and size based on the tab group’s. Adding and removing tabs uses similar methods to add/remove empty tabs to the JTabbedPane. Read uitabgroup’s schema.m for details.

A drawback of this complex mechanism is the absence of a single customizable Java object. The benefit is that it allows us to place any Matlab content within the tabs, including plot axes which cannot be added to Java containers. Had uitabgroup been a Java container, we could not add axes plots or images to its tabs. In my humble opinion, Matlab’s tab implementation is an ingenious piece of engineering.

Here’s a simple tab-group adapted from uitabgroup’s help section:

hTabGroup = uitabgroup; drawnow;
tab1 = uitab(hTabGroup, 'title','Panel 1');
a = axes('parent', tab1); surf(peaks);
tab2 = uitab(hTabGroup, 'title','Panel 2');
uicontrol(tab2, 'String','Close', 'Callback','close(gcbf)');

(recent Matlab releases throw a warning when using this code: either add the ‘v0′ input arg to uitabgroup and uitab calls, or suppress the MATLAB:uitabgroup:MigratingFunction warning)

Here, the returned uitabgroup object hTabGroup is actually a Matlab container (deriving from uiflowcontainer) that always displays two elements: the Java tab-group, and the active Matlab uicontainer (the active tab’s contents). Understanding this, hTabGroup’s FlowDirection property becomes clear. However, it is better to use hTabGroup’s TabLocation property, which accepts ‘top’, ‘bottom’, ‘left’ and ‘right’:

TabLocation = 'top'

TabLocation = 'top'

TabLocation = 'left'

TabLocation = 'left'

Another hTabGroup property of interest is Margin, which sets the margin in pixels before each of the displayed elements – not just between them as might be expected: Increasing Margin (default=2 pixels) increases the gap between the tab group and the active tab’s contents, but also the gap between the tab group and figure edge:

TabLocation = 'bottom', Margin = 20   TabLocation = 'left', Margin = 20

Margin = 20

Tabs can be selected programmatically, by setting hTabGroup’s SelectedIndex property. Reading this property is useful when setting tab-selection callbacks using the SelectionChangeFcn property:

set(hTabGroup,'SelectionChangeFcn',@myCallbackFcn);
set(hTabGroup,'SelectedIndex',2);   % activate second tab

(R2010b pre-release documentation has some incorrect information about this, which I have reported. Unfortunately, I cannot disclose any additional details here since usage of the pre-release implies an NDA. When the official release is made, I will update this post accordingly).

Additional control over the tab group’s behavior can be achieved by customizing the underlying Java object. This object is not directly exposed by uitabgroup, but can be found using the FindJObj utility or via the hidden ApplicationData. Remember that Java objects use 0-based indexing so tab #1 is actually the second tab. Also remember that HTML is accepted just as in any other Swing-based label:

% Get the underlying Java reference using FindJObj
jTabGroup = findjobj('class','tabgroup');
 
% A direct alternative for getting jTabGroup
jTabGroup = getappdata(handle(hTabGroup),'JTabbedPane');
 
% Now use the Java reference to set the title, tooltip etc.
jTabGroup.setTitleAt(1,'Tab #2');
jTabGroup.setTitleAt(1,'<html><b><i><font size=+2>Tab #2');
jTabGroup.setToolTipTextAt(1,'Tab #2');
 
% Disabling tabs can only be done using the Java handle:
jTabGroup.setEnabledAt(1,0);  % disable only tab #1 (=2nd tab)
jTabGroup.setEnabled(false);  % disable all tabs

A future post will describe tab customization, including fonts, colors, icons and even addition of close buttons as in modern web browsers.

tabdlg

tabdlg is a related semi-documented and unsupported uitool that, like uitabgroup, creates a tabbed user interface. However, unlike uitabgroup, tabdlg uses plain-vanilla Matlab, without reliance on Java (well, actually all Matlab GUI controls ultimately rely on Java, but tabdlg does not use any Java beyond that). The end result looks less professional than uitabgroup, but it works even when Java does not.

tabdlg has an extensive help section, so it will not be detailed here. In brief, the input parameters specify the tab labels, dimensions, offsets, callbacks, font, default tab, sheet dimensions and parent figure. Here is a sample usage, taken from tabdlg’s help section. This code is executed whenever tabdlg is invoked without any input arguments:

tabdlg left tab

tabdlg left tab

tabdlg right tab

tabdlg right tab

File Exchange alternatives

There are many implementations of tab panels in the Matlab File Exchange. Matlab’s official Desktop Blog had an article about one specific example, which was that week’s Peek of the Week, and relied on adjacent buttons that are easy to implement, but in my personal opinion are a far cry from our expectations of a tab panel.

Better FEX utilities are: Multiple Tab GUI, Highlight Tab Objects easily, and best of all: uitabpanel or TabPanel Constructor.

Another very recent submission was this week’s POTW. This utility gives a professional (although somewhat non-standard) look, and is very easy to program – an excellent utility indeed.

All of the numerous tab-panel FEX utilities, as well as the fact that tab-panels are one of the most searched-for terms in this website, indicate the Matlab community’s desire to have supported native-looking tab-panel GUI in Matlab. Perhaps after 6 years it is time to bring uitab and uitabgroup into the light?

Plot performance

Wednesday, June 16th, 2010

I recently consulted to a client who wanted to display an interactive plot with numerous data points that kept updating in real-time. Matlab’s standard plotting functions simply could not keep up with the rate of data change. Today, I want to share a couple of very simple undocumented hacks that significantly improve plotting performance and fixed my problem.

I begin by stating the obvious: whenever possible, try to vectorize your code, preallocate the data and other performance-improving techniques suggested by Matlab. Unfortunately, sometimes (as in my specific case above) all these cannot help. Even in such cases, we can still find important performance tricks, such as these:

Performance hack #1: manual limits

Whenever Matlab updates plot data, it checks whether any modification needs to be done to any of its limits. This computation-intensive task is done for any limit that is set to ‘Auto’ mode, which is the default axes limits mode. If instead we manually set the axes limits to the requested range, Matlab skips these checks, enabling much faster plotting performance.

Let us simulate the situation by adding 500 data points to a plot, one at a time:

>> x=0:0.02:10; y=sin(x);
>> clf; cla; tic;
>> drawnow; plot(x(1),y(1)); hold on; legend data;
>> for idx = 1 : length(x); plot(x(idx),y(idx)); drawnow; end;
>> toc
 
Elapsed time is 21.583668 seconds.

simple plot with 500 data points

simple plot with 500 data points

And now let’s use static axes limits:

>> x=0:0.02:10; y=sin(x);
>> clf; cla; tic; drawnow; 
>> plot(x(1),y(1)); hold on; legend data;
 
>> xlim([0,10]); ylim([-1,1]);  % static limits
 
>> for idx = 1 : length(x); plot(x(idx),y(idx)); drawnow; end;
>> toc
 
Elapsed time is 16.863090 seconds.

Note that this trick is the basis for the performance improvement that occurs when using the plot’s undocumented set of LimInclude properties.

Of course, setting manual limits prevents the axes limits from growing and shrinking automatically with the data, which can actually be a very useful feature sometimes. But if performance is important, we now know that we have this tool to improve it.

Performance hack #2: static legend

Hack #1 gave us a 22% performance boost, but we can do much better. Running the profiler on the code above we see that much of the time is spent recomputing the legend. Looking inside the legend code (specifically, the legendcolorbarlayout function), we detect several short-circuits that we can use to make the legend static and prevent recomputation:

>> x=0:0.02:10; y=sin(x);
>> clf; cla; tic; drawnow; 
>> plot(x(1),y(1)); hold on; legend data;
 
>> xlim([0,10]); ylim([-1,1]);  % static limits
 
>> % Static legend
>> set(gca,'LegendColorbarListeners',[]); 
>> setappdata(gca,'LegendColorbarManualSpace',1);
>> setappdata(gca,'LegendColorbarReclaimSpace',1);
 
>> for idx = 1 : length(x); plot(x(idx),y(idx)); drawnow; end;
>> toc
 
Elapsed time is 5.209053 seconds.

Now this is much much better – a 76% performance boost compared to the original plot (i.e., 4 times faster!). Of course, it prevents the legend from being dynamically updated. Sometimes we actually wish for this dynamic effect (last year I explained how to use the legend’s undocumented -DynamicLegend feature for even greater dynamic control). But when performance is important, we can still display a legend without its usual performance cost.

In conclusion, I have demonstrated that Matlab performance can often be improved significantly, even in the absence of any vectorization, by simply understanding the internal mechanisms and bypassing those which are irrelevant in our specific case.

Have you found other similar performance hacks? If so, please share them in the comments section below.

Matlab layout managers: uicontainer and relatives

Wednesday, June 9th, 2010

When designing Matlab applications, we can either use Matlab’s designer (guide), or manually position each GUI component programmatically, using its Position property. Matlab lacks the layout managers so common in Java, that enable easy relative component positioning, taking into account dynamic container size, components spacing weights etc. Of course, we can always trap the container’s ResizeFcn callback to update our layout, but doing so is one royal pain in the so-and-so…

Luckily, there is (of course) an undocumented solution to this problem, and at the public’s demand I will detail it below. It doesn’t solve all layout-management needs, but it goes a long way. Most importantly, it uses pure Matlab – no Java knowledge whatsoever is needed.

uicontainer

Matlab’s uicontainer family (uicontainer, uiflowcontainer and uigridcontainer) consists of container objects that enable customizable layout management of contained components. Uicontainers can contain any Matlab component that may have a uipanel handle as a Parent property. This includes uicontrols, plot axes etc., as well as other uicontainers.

The basic uicontainer object appears to be little more than a transparent container for contained objects. It can be used interchangeably with uipanel, which appears to be a specialized type of a uicontainer. Indeed, as MathWorks notes:
The UICONTAINER function is undocumented, and is not intended for direct use. The UIPANEL function should be used instead, as it provides more functionality.

In some cases, Matlab itself uses uicontainer instead of uipanel: for example, ActiveX controls are enclosed within transparent uicontrol objects when added to a figure:

>> [hActivex,hContainer] = actxcontrol('OWC11.Spreadsheet.11');
>> get(hContainer,'Type')
ans =
uicontainer

uicontainer objects are not very customizable. For example, unlike uipanels, uicontainers have no titles or borders. We would therefore usually prefer to use uipanels, as Mathworks suggested above. An exception to this rule is a case where we need to derive our own customized container class. An example of this is found in %matlabroot%/toolbox/matlab/uitools/@uitools/@uitab/schema.m, which derives uicontainer to create a uitab container (which will be described in a future article).

Relatives of uicontainer are more useful in general: uiflowcontainers and uigridcontainers act similarly to Java’s layout managers – specifically, FlowLayout and GridLayout. I expect to see additional layout managers incarnated within Matlab uicontainers in future Matlab versions (perhaps in the R2010b pre-release that came out today – I can’t wait to see…).

uiflowcontainer

uiflowcontainer is a uicontainer that enables adding uicontrols to the container without specifying an exact position as would be required for uicontainer or uipanel (actually, positions may be specified, but they are simply ignored).

By default, objects are added from the top-left corner, depending on the uiflowcontainer’s available space and dimensions: if width > height then rightward, otherwise downward. If the container’s dimensions change, for example by resizing the figure window, then the container’s components will automatically be resized accordingly:

hc = uiflowcontainer('Units','norm','Position',[.1,.1,.8,.8]);
h1 = uicontrol('string','1','parent',hc);
h2 = uicontrol('string','2','parent',hc);
h3 = uicontrol('string','3','parent',hc);

'Auto' - before resizing figure

'Auto' - before resizing figure

…and after resizing

…and after resizing

The components flow direction within the container may be modified by setting the uiflowcontainer’s FlowDirection property from its default value of ‘Auto’ to ‘AutoReverse’, ‘BottomUp’, ‘TopDown’, ‘LeftToRight’, or ‘RightToLeft’:

set(hc,'FlowDirection','BottomUp')
set(hc,'FlowDirection','RightToLeft')

'BottomUp'

'BottomUp'

'RightToLeft'

'RightToLeft'

Spacing between the components and the container’s border, and between themselves, may be controlled via the Margin property. By default, Margin is set to 2 (pixels):

Margin = 2 (default)

Margin = 2 (default)

Margin = 10

Margin = 10

The advantage of using uiflowcontainer is its automatic resizing and positioning of components. Notice how we simply specified the uiflowcontainer’s handle as the control’s parent, and got all this functionality out-of-the-box!

If we need to use fixed-dimensions components, we can use uicontrol’s undocumented properties HeightLimits and WidthLimits, each of which is a 2-element numeric vector specifying the minimal and maximal allowed value for the height or width (both of these vectors are [2,Inf] by default). uiflowcontainer tries to accommodate the requested limits by stretching or compressing its components (we need to resize the figure for the component resizing to become visible):

set(h1, 'HeightLimits',[10,20], 'WidthLimits',[30,30])
set(h2, 'HeightLimits',[50,50])
set(h3, 'HeightLimits',[2,inf])   % =default value

WidthLimits set

WidthLimits set

Sometimes, however, no amount of component resizing is enough to fully contain all components within the uiflowcontainer:

set(h2, 'WidthLimits',[150,150])
set(h3, 'HeightLimits',[50,50])  % resize figure to see effect

WidthLimits set

WidthLimits set

Note: uiflowcontainer normally ignores the specified limits if they would cause the component to stretch beyond the container boundaries. This happens unless the limits are identical (as in the preceding example), which informs uiflowcontainer that it has no judgment in the component’s dimensions.

In more complex cases, consider coding your own customized class deriving from uiflowcontainer. An example for such a customization can be seen in %matlabroot%/toolbox/matlab/uitools/@uitools/@uitabgroup/schema.m, which derives uiflowcontainer to create a uitabgroup container.

Components within a uiflowcontainer are ordered according to the order they were added to the container. This order can be modified by rearranging the handles in the container’s Children property, or by using the uistack function which does the same. Note that a side-effect of this is that the components dimensions are re-normalized:

uistack(h2,'top')

uistack(h2,'top')

uistack(h2,'bottom')

uistack(h2,'bottom')

uigridcontainer

uigridcontainer is similar to uiflowcontainer in its specialization of the layout: in this case, the container is divided into a transparent grid of N-by-M cells (1×1 by default), each of which can contain its own component:

hc = uigridcontainer('Units','norm','Position',[.1,.1,.8,.8]);
set(hc, 'GridSize',[2,3]);  % default GridSize is [1,1]
h1 = uicontrol('string','1','parent',hc);
h2 = uicontrol('string','2','parent',hc);
h3 = uicontrol('string','3','parent',hc);
h4 = axes('parent',hc); x = -4:.1:4; plot(h4,x,sin(x));
set(h4,'YTickLabel',[],'XTickLabel',[]);

A 2-by-3 uigridcontainer

A 2-by-3 uigridcontainer

The grid cells relative size can be controlled via the HorizontalWeight and VerticalWeight properties (set to NaN by default). These properties should be a numeric vector the same size as the corresponding number of cells. The property values are not important – only their relative values are used to control the relative cell dimensions. The EliminateEmptySpace property (default=’off’) controls whether empty grid rows/columns are eliminated from the container or displayed. As in uiflowcontainers, the Margin property controls the spacing between the internal components and borders:

set(hc, 'HorizontalWeight',[6,3,1], 'VerticalWeight',[0.2,0.5])
delete([h2,h3]);  % only h1,h4 remain
set(hc,'EliminateEmptySpace','on')

Non-equal grid weights

Non-equal grid weights

EliminateEmptySpace='on'

EliminateEmptySpace='on'

...and 'off'

...and 'off'

Other layout alternatives

Brad Phelan of XTargets has created Matlab equivalents of Java’s BorderLayout and SpringLayout. The advantage of using Brad’s layout managers is that they appear to have full Matlab interoperability, including the ability to add Matlab components, unlike Java’s layout managers.

A File Exchange contributor named Jason has added a GridBagLayout implementation, mimicking Java’s well-known GridBagLayout.

Additional and more flexible layout managers are available in Java (one of my favorites is JGoodies Forms, which is pre-bundled with Matlab). Just remember the limitation that no Matlab component (such as GUI controls or plot axes) can be added to Java containers. Therefore, feel free to use these Java containers as long as their contained GUI is limited to Java components (JButton, JComboBox etc.).

Other uitools

Today’s article about uicontainer and its relatives was the first of several posts that will describe undocumented functions that reside in the %matlabroot%/toolbox/matlab/uitools folder. Feel free to look within this folder for other interesting undocumented functions. Most of these functions are semi-documented, meaning that they have a usable help-section hidden within the m-file (type “edit uicontainer.m” for example). Many have existed more-or-less unchanged for many releases. Note that there is no guarantee that they will remain in future releases. When using unsupported functionality, always code defensively.

Modifying default toolbar/menubar actions

Wednesday, June 2nd, 2010

Did you ever wish to modify Matlab’s default toolbar/menubar items?

I recently consulted to a client who needed to modify the default behavior of the legend action in the toolbar, and the corresponding item on the main menu (Insert / Legend). The official version is that only user-added items can be customized, whereas standard Matlab items cannot.

Luckily, this can indeed be done using simple pure-Matlab code. The trick is to get the handles of the toolbar/menubar objects and then to modify their callback properties.

Default legend insertion action

Default legend insertion action

Using the toolbar/menubar item handles

Getting the handles can be done in several different ways. In my experience, using the object’s tag string is often easiest, fastest and more maintainable. Note that the Matlab toolbar and main menu handles are normally hidden (HandleVisibility = ‘off’). Therefore, in order to access them we need to use the findall function rather than the better-known findobj function. Also note that to set the callbacks we need to access differently-named properties: ClickedCallback for toolbar buttons, and Callback for menu items:

hToolLegend = findall(gcf,'tag','Annotation.InsertLegend');
set(hToolLegend, 'ClickedCallback',{@cbLegend,hFig,myData});
 
hMenuLegend = findall(gcf,'tag','figMenuInsertLegend');
set(hMenuLegend, 'Callback',{@cbLegend,hFig,myData});

As a side note, two undocumented/unsupported functions, uitool(hFig,tagName) and uigettoolbar, also retrieve toolbar items. Since using findall is so simple and more supported, I suggest using the findall approach.

To see the list of available toolbar/menubar tags, use the following code snippet:

% Toolbar tag names:
>> hToolbar = findall(gcf,'tag','FigureToolBar');
>> get(findall(hToolbar),'tag')
ans = 
    'FigureToolBar'
    'Plottools.PlottoolsOn'
    'Plottools.PlottoolsOff'
    'Annotation.InsertLegend'
    'Annotation.InsertColorbar'
    'DataManager.Linking'
    'Exploration.Brushing'
    'Exploration.DataCursor'
    'Exploration.Rotate'
    'Exploration.Pan'
    'Exploration.ZoomOut'
    'Exploration.ZoomIn'
    'Standard.EditPlot'
    'Standard.PrintFigure'
    'Standard.SaveFigure'
    'Standard.FileOpen'
    'Standard.NewFigure'
    ''
 
% Menu-bar tag names:
>> get(findall(gcf,'type','uimenu'),'tag')
ans = 
    'figMenuHelp'
    'figMenuWindow'
    'figMenuDesktop'
    'figMenuTools'
    'figMenuInsert'
    'figMenuView'
    'figMenuEdit'
    'figMenuFile'
    'figMenuHelpAbout'
    'figMenuHelpPatens'
    'figMenuHelpTerms'
    'figMenuHelpActivation'
    'figMenuDemos'
    'figMenuTutorials'
    'figMenuHelpUpdates'
    'figMenuGetTrials'
    'figMenuWeb'
    'figMenuHelpPrintingExport'
    'figMenuHelpAnnotatingGraphs'
    'figMenuHelpPlottingTools'
    'figMenuHelpGraphics'
    ''
    ''                    <= Note the missing tag names...
    ''
    'figMenuToolsBFDS'    <= note the duplicate tag names...
    'figMenuToolsBFDS'
    'figDataManagerBrushTools'
    'figMenuToolsAlign'
    'figMenuToolsAlign'
    ... (plus many many more...)

Unfortunately, as seen above, Matlab developers forgot to assign tags to some default toolbar/menubar items. Luckily, in my particular case, both legend handles (toolbar, menu) have valid tag names that can be used: ‘Annotation.InsertLegend’ and ‘figMenuInsertLegend’.

If an item’s tag is missing, you can always find its handle using its Parent, Label, Tooltip or Callback properties. For example:

hPrintMenuItem = get(findall(gcf,'Label','&Print...'));

Note that property values, such as the tag names or labels, are unsupported and undocumented. They may change without warning or notice between Matlab releases, and have indeed done so in the past. Therefore, if your code needs to be compatible with older Matlab releases, ensure that you cover all the possible property values, or use a different way to access the handles. While using the tag name or label as shown above is considered “Low risk” (I don’t expect it to break in the near future), their actual values should be considered somewhat more risky and we should therefore code defensively.

Another simple example: Print Preview

As another simple and very useful example, let’s modify the default Print action (and tooltip) on the figure toolbar to display the Print-Preview window rather than send the figure directly to the printer:

Matlab's default toolbar Print action

Matlab's default toolbar Print action

hToolbar = findall(gcf,'tag','FigureToolBar');
hPrintButton = findall(hToolbar,'tag','Standard.PrintFigure');
set(hPrintButton, 'ClickedCallback','printpreview(gcbf)', ...
                  'TooltipString','Print Preview');

Matlab's Print Preview window

Matlab's Print Preview window

More advanced customization of the toolbar and menu items are possible, but require a bit of Java code. Examples of toolbar customizations were presented in past articles (here and here). A future article will explain how to customize menu items.

Have you found a nifty way to customize the menubar or toolbar? If so, please share it in the comments section below.

New information on HG2

Monday, May 10th, 2010

Last week I posted a couple of articles on the undocumented feature function and Matlab’s apparent move towards a class-based Handle-Graphics system called HG2.

Apparently I caused a bit of a stir…

This is normally a weekly blog. But I wanted to share some additional relevant information as well as some interesting tips I received in private communications. Please note that much of the following is speculation or guesswork and may be incorrect or even entirely wacky. Please read the following with more than the usual grain of skepticism…

UDD

A bit of historical background: Matlab’s existing Handle Graphics system is based on UDD (Unified Data Definition?) objects. Prior to Matlab Release 12 (a.k.a. 6.0) back in 2000, Matlab was written exclusively in C and HG and Simulink used differing approaches to objects in the MathWorks codebase. UDD was then added for R12 using C++ code with C wrappers for internal use by the MathWorks developers. UDD enabled a new unified approach for HG and Simulink (recall the major overhaul to the Matlab interface in that release, which also modified the GUI to be Java-based). While the HG handles remained numeric, behind the scenes they relied on the new UDD system, which remained undocumented.

Matlab users who wished to leverage UDD classes could (and still can) access it via some undocumented interface functions: handle, handle.listener, handle.event, classhandle, schema.prop, schema.class, schema.event (and other schema.* functions), findprop, findclass, findevent and several others. Some of these functions were mentioned in past articles on this blog, and others will perhaps be explained in future articles. You can find numerous mentions and usage examples of UDD in the Matlab codebase that is part of each Matlab installation.

In /toolbox/matlab/helptools/+helpUtils/@HelpProcess/getHelpText.m we can see a related feature (feature(‘SearchUUDClassesForHelp’, flag)) which can apparently be used to allow access to the h1 line and help text for UDD methods. Unfortunately, I have not found any relevant UDD candidates for this. I would be very happy to hear if you know of any objects/methods which have a UDD help section.

MCOS

Perhaps Matlab’s Class Object System (MCOS), first introduced in R14 (a.k.a. 7.0, released in 2004) grew out of the UDD beginnings, and perhaps it was developed separately. The fact is that it shared several terms and concepts (“schema”, properties meta-data, events) with UDD, although no direct interaction between UDD and MCOS exists, AFAIK.

As an interesting side-note, MCOS was introduced as an opt-in beta-testing feature in R14SP2 (7.0.4, released in 2005). This beta feature cannot be found in the official online version of the R14SP2 release notes, but can be found in the hardcover version pages 10-11:
New syntax and features for creating and working with classes in MATLAB. For R14SP2, these features are at a Beta level. If you are interested in being a Beta tester for these features, see “Beta Test the MATLAB Class System” on page 11.

Beta Test the MATLAB Class System. MATLAB 7.0.4 includes a Beta version of new syntax and features for working with classes in MATLAB, which simplify and expand object-oriented programming capabilities in MATLAB. Participation in this Beta program is open only to customers who are current
on their maintenance for MATLAB. Trial passcodes will not be made available for this Beta test. If you are interested in being a Beta tester for these features, register on the MathWorks Web site, at http://www.mathworks.com/products/beta/r14sp2/signup_newfeatures.html. (needless to say, this webpage was since removed…)

The MCOS syntax has changed between releases and was not very stable, until it was formally introduced in R2008a (a.k.a. 7.6, released in 2008). You can look at /toolbox/matlab/iofun/@memmapfile/memmapfile.m to see the MCOS evolution from R14 onward.

HG2

The new HG2 appears to be a merger of MCOS and UDD, using MCOS infrastructure for UDD classes and properties, finally throwing away the old numeric handles and C wrappers for the more powerful object-oriented approach.

For the transition period between HG and HG2, there seems to be a dedicated feature: feature(‘HGtoCOS’, handle) apparently converts a UDD (“HG”) handle into an HG2 (“COS”) handle. You can also use feature(‘HGtoCOS’, 0) to obtain an MCOS object of the desktop (=handle 0). Here is a sample result on a Matlab 2009 release:

>> hFig = figure
hFig =
     1
 
>> fmcos = feature('HGtoCOS', hFig)
fmcos =
 
  gbtmcos.figure handle
 
  Package: gbtmcos
 
  Properties:
                 Alphamap: [1x64 double]
             BeingDeleted: 'off'
               BusyAction: 'queue'
            ButtonDownFcn: []
                 Children: [0x1 double]
                 Clipping: 'on'
          CloseRequestFcn: 'closereq'
                    Color: [0.8000 0.8000 0.8000]
                 Colormap: [64x3 double]
                      ...  (all the regular figure properties)

Note that in that here, the new object package was called GBTMCOS – perhaps meaning a GBT version of the MCOS system. This corresponds to the feature(‘useGBT2′) that I reported in the features article. I have absolutely no idea what GBT stands for, whether it is a synonym for HG2 or not exactly, and what the differences are between GBT1.5 and GBT2. In any case, in R2010a, the same feature(‘HGtoCOS’, handle) code returns a ui.figure object: “GBTMCOS” was simply renamed “UI”.

I do not know how to convert an HG2 back to a UDD/HG handle. None of the following appears to work:

>> fmcos.getdoubleimpl
ans =
    -1
 
>> fmcos.double
ans =
on
 
>> double(fmcos)
ans =
    -1
 
>> handle(fmcos)
??? Error using ==> handle
Cannot convert to handle.

I would love to hear any additional information on these subjects, either anonymously or on record. You can use either a direct mail (see link at the top-right of this page) or the comments section.

Matlab’s HG2 mechanism

Friday, May 7th, 2010

A few days ago I posted a lengthy article about Matlab’s undocumented feature function. In it, I mentioned a feature called HG2, that I believe merits a dedicated article, due to its potential high impact on future Matlab releases.

HG2, which presumably stands for “Handle Graphics 2nd generation”, was already reported in the past as an undocumented hidden figure property (UseHG2). In normal Matlab usage, this boolean property is ‘off’:

>> get(gcf,'usehg2')
ans =
off

HG2 is mentioned in quite a few Matlab files:

  • clf.m, hgload.m, ishg2figure.m, datetick.m, linkdata.m, linkplotfunc.m, cameratoolbar, /bin/registry/handle_graphics.xml, /ja/xlate and many more
  • uimodemanager.m (and others) temporarily disables a ‘MATLAB:handle:hg2′ warning
  • defaulterrorcallback.m mentions ‘MATLAB:HG2:SceneNode’ and ‘MATLAB:HG2:Property’
  • getplotbrowserproptable.m mentions several special HG2 types (hg2.Line, hg2.Lineseries, hg2.Patch etc.)
  • There’s even a dedicated /toolbox/matlab/graphics/private/ishg2figure.m function that determines whether a figure contains any HG2 graphics based on the existence of ‘hg2peer’ appdata (getappdata(fig,’hg2peer’)).
  • /toolbox/matlab/plottools/@objutil/@eventmanager/schema.m (and a few others) has the following comment:
     % may contain either UDD or MCOS listeners during the hg2 migration.

Obviously, much effort was invested in HG2 functionality. The fact that HG2 has been under development at least since 2007 (when I first discovered and reported it) seems to indicate a major upheaval in Matlab’s Handle Graphics mechanism. This hunch is reinforced by cryptic comments made by MathWorks personnel over the past few years that they are indeed looking at the HG system, which in their opinion is nearing its limitations. Perhaps I’m mixing unrelated stuff here, but it does make sense in light of Matlab’s push of its OOP class system over the past few releases.

To preview this HG2 system, we need to turn it on. Unfortunately, when we set the figure’s UseHG2 to ‘on’ there doesn’t seem to be any visible effect. However, this changes after we use the corresponding ‘UseHG2′ feature using the feature function (this caused lots of nasty-looking errors in past releases but works ok in R2010a):

>> feature('usehg2',1)

The /ja/xlate file (which is used in conjunction with the undocumented xlate function to translates Matlab messages from English to Japanese) has another key to unlocking HG2: This file contains the following message: “feature(‘useGBT2′) is only available when Matlab is started with -hgVersion 2 option.“. So let’s do as the xlate message advises and start a new Matlab session with the undocumented “-hgVersion 2″ command-line option. Now feature(‘usehg2′) is true by default and we can test the HG2 system.

Matlab looks basically the same in HG2 as in HG1. All the regular graphic functions behave just as we would expect from the existing (HG1) implementation. There are two major differences though:

  • the figure toolbars/menubars are missing and cannot be shown, even when the relevant figure properties are set. Without a menubar and toobar, Matlab figures are extremely less useful than their HG1 counterparts. This problem does not occur in HG2-enabled figures in the regular Matlab session (i.e., without using the “-hgVersion 2″ command-line option)
  • all the HG handles are now Matlab class handles rather than numeric values (These class handles are similar to those returned today (in HG1) using the undocumented handle function). There’s an exception to this rule: in regular Matlab sessions (i.e., without using the “-hgVersion 2″ command-line option), after setting the ‘UseHG2′ feature on, the returned figure handle is numeric rather than a class handle (but if you now plot within this figure you get the class object handles). Here’s the output from the “-hgVersion 2″ Matlab session:
    >> hFig = figure
    hFig = 
    	ui.Figure
     
    >> hLine = plot(1:5)
    hLine = 
    	hg2.Lineseries
     
    >> get(hLine,'Parent')
    ans = 
    	hg2.Axes
     
    >> findprop(gcf,'Tag')
    ans = 
      meta.property handle
      Package: meta
     
      Properties:
                       Name: 'Tag'
                Description: 'Tag PropInfo'
        DetailedDescription: ''
                  GetAccess: 'public'
                  SetAccess: 'public'
                  Dependent: 1
                   Constant: 0
                   Abstract: 0
                  Transient: 0
                     Hidden: 0
              GetObservable: 1
              SetObservable: 1
                   AbortSet: 0
                  GetMethod: []
                  SetMethod: []
                 HasDefault: 0
              DefiningClass: [1x1 meta.class]
      Methods, Events, Superclasses
     
    >> methods(gcf)
     
    Methods for class ui.Figure:
     
    Figure                  disp                    get                     horzcat                 lt                      subsasgn                
    addlistener             double                  getParentImpl           ishghandlewithargs      ne                      vertcat                 
    addprop                 eq                      getSceneViewer          ishghandlewoargs        notify                  
    applydefaultproperties  findobj                 getdisp                 isvalid                 reset                   
    cat                     findprop                gt                      java                    set                     
    delete                  ge                      hgclose                 le                      setdisp                 
     
    Static methods:
     
    getDefaultObject        
     
    >> methods(gcf,'-full')
     
    Methods for class ui.Figure:
     
    ui.Figure lhs1 Figure(rhs0)
    event.listener L addlistener(handle sources, char vector eventname, function_handle scalar callback)  % Inherited from hg2utils.HGHandle
    event.proplistener L addlistener(handle sources, meta.property propertyname, char vector eventname, function_handle scalar callback)  % Inherited from hg2utils.HGHandle
    event.proplistener L addlistener(handle sources, string propertyname, char vector eventname, function_handle scalar callback)  % Inherited from hg2utils.HGHandle
    event.proplistener L addlistener(handle sources, cell propertyname, char vector eventname, function_handle scalar callback)  % Inherited from hg2utils.HGHandle
    meta.property prop addprop(handle scalar object, string propname)  % Inherited from dynamicprops
    applydefaultproperties(HGHandle object, rhs1)  % Inherited from hg2utils.HGHandle
    HeterogeneousHandle lhs3 cat(double rhs0, rhs1, rhs2)  % Inherited from HeterogeneousHandle
    delete(handle obj)  % Inherited from handle
    disp(object)  % Inherited from hg2utils.HGHandle
    lhs1 double(handle object)  % Inherited from hg2utils.HGHandle
    logical TF eq(A, B)  % Inherited from hg2utils.HGHandle
    handle output findobj(handle object, varargin)  % Inherited from hg2utils.HGHandle
    meta.property prop findprop(handle scalar object, string propname)  % Inherited from handle
    logical TF ge(A, B)  % Inherited from handle
    varargout get(hgsetget object, rhs1)  % Inherited from hg2utils.HGHandle
    Static HeterogeneousHandle lhs0 getDefaultObject  % Inherited from hg2utils.HGHandle
    lhs2 getParentImpl(handle scalar object, rhs1)  % Inherited from hg2utils.HGObject
    lhs2 getSceneViewer(handle scalar object, rhs1)  % Inherited from ui.UISceneViewerParent
    getdisp(hgsetget rhs0)  % Inherited from hgsetget
    logical TF gt(A, B)  % Inherited from handle
    hgclose(handle scalar object)
    HeterogeneousHandle lhs2 horzcat(rhs0, rhs1)  % Inherited from HeterogeneousHandle
    lhs2 ishghandlewithargs(handle scalar object, rhs1)  % Inherited from hg2utils.HGObject
    lhs1 ishghandlewoargs(handle scalar object)  % Inherited from hg2utils.HGObject
    logical validity isvalid(handle obj)  % Inherited from handle
    j java(JavaVisible scalar h)  % Inherited from JavaVisible
    logical TF le(A, B)  % Inherited from handle
    logical TF lt(A, B)  % Inherited from handle
    logical TF ne(A, B)  % Inherited from hg2utils.HGHandle
    notify(handle sources, string eventname, event.EventData scalar eventdata)  % Inherited from handle
    notify(handle sources, string eventname)  % Inherited from handle
    reset(handle scalar object)  % Inherited from hg2utils.HGHandle
    varargout set(hgsetget object, rhs1)  % Inherited from hg2utils.HGHandle
    setdisp(hgsetget rhs0)  % Inherited from hgsetget
    varargout subsasgn(rhs0, rhs1, rhs2, rhs3)  % Inherited from HeterogeneousHandle
    HeterogeneousHandle lhs2 vertcat(rhs0, rhs1)  % Inherited from HeterogeneousHandle

The latest Matlab releases have shown how the Matlab handle class can be extended using user-created derived classes. It stands to reason that so do all the new HG2 objects. This would theoretically enable Matlab programmers to customize graphic objects appearance to suit their needs in a more intuitive manner than possible using HG1.

Many mysteries remain:

  • is it possible to mix HG1 and HG2 objects in the same figure?
  • can we switch between HG1 and HG2 in the same Matlab session (I got some crashes…)?
  • why is there a need for the separate feature options ‘UseHG2′, ‘UseGBT2′ and ‘HGUsingMatlabClasses’?
  • why is there a need for “-hgVersion 2″ Matlab sessions if we can simply use feature(‘UseHG2′)?
  • is it possible to restore the figure menubar and toolbar in “-hgVersion 2″ Matlab sessions?
  • is it indeed possible to extend HG2 objects using user-defined classes? and if so, can we modify the appearance/behavior beyond what is available in the existing list of HG2 properties?
  • beyond changing numeric handles into class handles, are there any actual benefits to the HG2 system over HG1?
  • what is the difference between HG2, GBT2 and GBT1.5 (which are mentioned together as separate entities in cameratoolbar.m)?

HG2 is still buggy, which explains why it is still not officially released. For example, the inspect(gca) function crashes Matlab, figure toolbars/menubars are missing, and some properties that are available in HG1 are missing in HG2. Also, we can add Java components to a Matlab figure using javacomponent as in HG1 (the returned container handles is a ui.HGJavaComponent class handle), but we get an error when we close the figure…

Still, with all this effort invested into HG2 I believe that it is only a matter of time before HG2 becomes officially released. This could happen perhaps even as soon as the upcoming R2010b release, but with the current state as seen above I suspect it will not happen before 2011. Also, my gut feeling is that Matlab will define any release that includes HG2 as a major release and we will finally have Matlab 8.0.

I would dearly love to hear any further information anyone discovers about HG2 and related issues. Please share your findings by email or in the comments section below.

Plot LimInclude properties

Wednesday, March 31st, 2010

Concluding my three-part mini-series on hidden and undocumented plot/axes properties, I would like to present a set of properties that I find very useful in dynamic plots: XLimInclude, YLimInclude, ZLimInclude, ALimInclude and CLimInclude. These properties, which are relevant for plot/axes objects, have an ‘on’ value by default. When set to ‘off’, they exclude their object from the automatic computation of the corresponding axes limits (XLim/YLim/ZLim/ALim/CLim).

For example, here’s a simple sine wave with a wavefront line marker. Note how the too-tall wavefront line affects the entire axes Y-limits:

cla;
t=0:.01:7.5;
plot(t,sin(t));
line('xdata',[7.5,7.5], 'ydata',[-5,5], 'color','r'); 
box off

Regular plot (YLimInclude on)

Regular plot (YLimInclude on)

This situation is quickly fixed using the YLimInclude property:

cla;
t=0:.01:7.5;
plot(t,sin(t));
line('xdata',[7.5,7.5], 'ydata',[-5,5], 'color','r', ...
     'YLimInclude','off'); 
box off

YLimInclude off

YLimInclude off

Beside the functional importance of this feature, it also has a large potential for improved application performance: I recently designed a monitor-like GUI for a medical application, where the data is constantly updated from an external sensor connected to the computer. The GUI presents the latest 10 seconds of monitored data, which bounce up and down the chart. A red wave-front line is presented and constantly updated, to indicate the current data position. Since the monitored data jumps up and down, the Y-limits of the monitor chart often changes, and with it I would need to modify the wavefront’s YData based on the updated axes YLim. This turned out to steal precious CPU time from the actual monitoring application. Came YLimInclude to the rescue, by letting me specify the wavefront line as:

hWavefront = line(..., 'YData',[-99,99], 'YLimInclude','off');

Now the wavefront line never needed to update its YData (only XData, which is much less CPU-intensive) – it always spanned the entire axes height, since [-99,99] were assured (in my particular case) to exceed the actual monitored data. This looked better (no flicker effects) and performed faster than the regular (documented) approach.

Note that although all these properties exist, to the best of my knowledge, for all Handle-Graphic plot objects, they are sometimes meaningless. For example, ZLimInclude is irrelevant for a 2D patchless plot; CLimInclude relates to the axes color limits which are irrelevant if you’re not using a colormap or something similar; ALimInclude relates to patch transparency (alpha-channel) and is irrelevant elsewhere. In these and similar cases, setting these properties, while allowed and harmless, will simply have no effect.

This concludes my mini-series of undocumented plot/axes properties. To recap, the other articles dealt with the LooseInset and LineSmoothing properties.

Have you found other similar properties or use-cases that you find useful? I will be most interested to read about them in the comments section below.

Axes LooseInset property

Wednesday, March 24th, 2010

Last week, I wrote an article about the hidden/undocumented LineSmoothing plot property. This week, I want to introduce another useful hidden/undocumented property – the plot axes’ LooseInset property. This follows on the wake of an email I received from a reader about this property, which had some new information for me (thanks Ben!).

Apparently, LooseInset, which is automatically set to a factory value of [0.13, 0.11, 0.095, 0.075], is used by Matlab axes to reserve a small empty margin around the axes, presumably to enable space for tick marks. These empty margins can be very annoying at times, especially when we have directly control on the axes contents.

figure; t=0:0.01:7; plot(t,2*sin(t));

Axes with default LooseInset values (note the excessive margins)

Axes with default LooseInset values
(note the excessive margins)

If you set Position to [0 0 1 1], the labels are cut-off; if you set Position to something like [0.05 0.05 0.9 0.9], you can get the labels to show up, but if you now resize the image the labels may be cut off… Similarly, setting TightInset also does not work.

Theoretically, the solution should be to set OuterPosition to [0 0 1 1]. This is supposed to make the axes (including labels) take up the entire figure. However, it usually over-estimates the required margins, causing wasted space. Using OuterPosition also causes unexpected behaviors with sub-plots.

Solution: simply set LooseInset to [0 0 0 0]:

set(gca, 'LooseInset', [0,0,0,0]);

Axes with empty LooseInset values

Axes with empty LooseInset values

To modify all future axes in the same way (i.e., have an empty LooseInset):

set(0,'DefaultAxesLooseInset',[0,0,0,0])

Clearing the LooseInset margins has a drawback: if the axes is zoomed or modified in such a way that the labels change, then the active axes plot region needs to shrink accordingly. For example:

Axes with empty LooseInset values, wide tick labels (note the changed plot region size)

Axes with empty LooseInset values, wide tick labels
(note the changed plot region size)

When determining the size of the axes, it seems that Matlab takes into account larger of the documented TightInset and the undocumented LooseInset. So, perhaps a better generic solution would be the one suggested by another blog reader:

set(gca,'LooseInset',get(gca,'TightInset'))

Note that the LooseInset property was first reported on CSSM back in 2007 (also here). The LooseInset property has remained hidden and undocumented to this day (Matlab 7.10, R2010a), although it has even featured in an official MathWorks Technical Solution to a reported problem about unexpected axes sizes last year.

p.s. – another undocumented property of Matlab axes, ContentsVisible, was described by Matt Whittaker in a comment on my original article that introduced undocumented properties.