All Matlab’s Handle Graphics (HG) property have default values. These values are used unless we specifically override the property value. For example, in R2012a, Matlab figure handles have 62 documented and 28 undocumented properties, all of which have some default value. When we create a new Matlab figure, we typically override only a handful of these properties.
For example, we might override the figure’s Name, NumberTitle, Position, Visible, Colormap and perhaps a few other properties. All the others are either read-only (i.e., un-settable), or left at their default values. This is also true for all HG objects: axes, images, plots, patches, uicontrols, annotations, Java control containers etc.
Matlab makes a distinction between factory and default values. Users can modify the default values, but not the factory values, which makes sense. In essence, user-specified property values override the default values, which in turn override the factory values. I find that this makes the process of using default values quite intuitive. I like this factory/default design.
Matlab has a dedicated doc page explaining how we can use, set and reset the default property values.
Unfortunately, MathWorks has not seen fit to explain how to get the full list of current default defaults, nor how to get the factory values. Today’s article provides the missing manual pages and completes the picture.
Accessing default and factory property values
To access any specific property’s default value, we need to compose a fictitious property name from the string ‘Default’ or ‘Factory’, followed by the object’s type (‘Figure’, ‘Axes’, ‘Line’ etc., as reported by the object’s Type property), and lastly the property name. For example: DefaultFigureColor or FactoryAxesUnits. As with all HG properties, these names are case insensitive. These fictitious properties all belong to Matlab’s root (0) handle.
We can now get and set the values of any of these fictitious properties (naturally, factory properties cannot be set):
>> get(0,'FactoryFigureUnits') ans = pixels >> get(0,'FactoryFigureColor') ans = 0 0 0 >> get(0,'DefaultFigureColor') ans = 0.8 0.8 0.8 >> set(0,'DefaultFigureColor','y'); % new figures will now have a yellow background color... >> set(0,'DefaultFigureColor','factory'); % resets the default value to the factory value [0,0,0]=black |
Note that since the default and factory property names are fictitious (i.e., dynamic properties that are parsed on-the-fly), they do not appear when you get(0), getundoc(0) or even uiinspect(0).
My uiinspect utility reports the factory values in its property-details panel, along with additional meta-data such as whether the properties are settable, readable etc.
Getting the full list of factory/default values
To get the long list of factory values, simply get a partial fictitious property name:
>> get(0,'factory') ans = factoryFigureAlphamap: [1x64 double] factoryFigureBusyAction: 'queue' factoryFigureButtonDownFcn: '' factoryFigureClipping: 'on' factoryFigureCloseRequestFcn: 'closereq' factoryFigureColor: [0 0 0] (... 655 additional properties ...) >> get(0,'default') ans = defaultTextColor: [0 0 0] defaultAxesXColor: [0 0 0] defaultAxesYColor: [0 0 0] defaultAxesZColor: [0 0 0] defaultPatchFaceColor: [0 0 0] defaultPatchEdgeColor: [0 0 0] defaultLineColor: [0 0 0] defaultFigureInvertHardcopy: 'on' defaultFigureColor: [0.8 0.8 0.8] defaultAxesColor: [1 1 1] defaultAxesColorOrder: [7x3 double] defaultFigureColormap: [64x3 double] defaultSurfaceEdgeColor: [0 0 0] defaultFigurePaperType: 'A4' defaultFigurePaperUnits: 'centimeters' defaultFigurePaperSize: [20.98404194812 29.67743169791] defaultFigurePosition: [200 200 560 420] >> get(0,'DefaultAxes') ans = defaultAxesXColor: [0 0 0] defaultAxesYColor: [0 0 0] defaultAxesZColor: [0 0 0] defaultAxesColor: [1 1 1] defaultAxesColorOrder: [7x3 double] |
We can see that the defaults list is much shorter than the factory list. There are very few actual default overrides of the factory values. In fact, if we try to get the default value of a property that was not overridden (e.g., DefaultFigureNumberTitle), Matlab is smart enough to return the factory value (in this case, FactoryFigureNumberTitle=’on’).
Hidden properties
Hidden (undocumented) properties are not shown by default, but you can always access them directly, and their list can also be seen if we set the root handle’s HideUndocumented property:
>> get(0,'FactoryAxesLooseInset') ans = 0.13 0.11 0.095 0.075 >> get(0,'DefaultPatchLineSmoothing') ans = off >> set(0,'DefaultLineLineSmoothing','on'); % default appears to be 'off' for Windows, 'on' for Macs >> set(0,'HideUndocumented','off') >> allPropDefaults = get(0,'factory'); >> length(fieldnames(allPropDefaults)) % 661 documented + 277 undocumented properties ans = 938 |
Factory values internals
For those interested in some internals, the factory values are stored (and can be accessed) via the object’s UDD reference, or rather the schema.prop reference of the properties (additional information on UDD properties can be found here). For example:
>> get(0,'FactoryFigurePosition') ans = 100 100 660 520 >> hProp = findprop(handle(gcf),'pos') hProp = schema.prop >> get(hProp) Name: 'Position' Description: '' DataType: 'figurePositionType' FactoryValue: [100 100 660 520] AccessFlags: [1x1 struct] Visible: 'on' GetFunction: [] SetFunction: [] >> hProp.FactoryValue ans = 100 100 660 520 |
Note that in this example, the FactoryFigurePosition value ([100 100 660 520]) is different than the DefaultFigurePosition value ([200 200 560 420]), which overrides it.
Conclusion
Setting default values enables easy setup of property values for all instances of an HG property in a Matlab session. It could be very tempting to add such setup to the startup.m file, so that such customizations automatically occur for all Matlab sessions. However, I strongly suggest against this: the moment you will try to run your application on any other computer or Matlab installation, you may find that your GUI/graphics look entirely different.
A much safer approach is to understand how these default values affect your application and then specifically set the desired property values in your m-code. This way, whatever the installation’s default values are, your application will always retain a consistent look-and-feel.
Have you found or ever used any interesting default or factory property value? If so, please share your experience in a comment.
I’ve been wondering about these defaults for a while now. Thanks for posting this.
It is not clear from your post, but you can also set default values of objects other than the root object. I often will generate a figure and then set its default values …
so that all the axes on that figure have a custom value.
One interesting note is that handle graphic objects including root are sub classes of the abstract base class
GObject
.GObject
defines 29 properties with 11 hidden properties. Sixteen of these properties have Factory values.Apart from get(0, ‘factory’) there’s (since MATLAB 2013a) the undocumented function rootfactoryvalues(), that also returns a structure with a lot of factory values. The list returned by the latter is much shorter, but contains values not returned by the former. I failed to see a pattern, but maybe someone else is more inclined to investigate further. 🙂
Thanks for this interesting post! It improved my understanding of the MATLAB graphics system, which is one of my weaknesses.
[…] are forgotten! Recently, the Undocumented Matlab Blog had a great post about these hidden defaultshttp://undocumentedmatlab.com/blog/getting-default-hg-property-values/. There are many other properties that can potentially be changed as […]
Hi,
Did they replaced the ‘0’ in
get(0,'FactoryFigureColor')
to ‘groot’ ->get(groot, 'FactoryFigureColor')
?@Royi – no,
get(0,'FactoryFigureColor')
works just fine for me: