<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Medium risk of breaking in future versions &#8211; Undocumented Matlab</title>
	<atom:link href="https://undocumentedmatlab.com/articles/category/presumed-future-risk/medium-risk-of-breaking-in-future-versions/feed" rel="self" type="application/rss+xml" />
	<link>https://undocumentedmatlab.com</link>
	<description>Professional Matlab consulting, development and training</description>
	<lastBuildDate>Sun, 09 Mar 2025 15:39:07 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.7.4</generator>
	<item>
		<title>Improving graphics interactivity</title>
		<link>https://undocumentedmatlab.com/articles/improving-graphics-interactivity?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=improving-graphics-interactivity</link>
					<comments>https://undocumentedmatlab.com/articles/improving-graphics-interactivity#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Sun, 21 Apr 2019 21:03:10 +0000</pubDate>
				<category><![CDATA[GUI]]></category>
		<category><![CDATA[Handle graphics]]></category>
		<category><![CDATA[Medium risk of breaking in future versions]]></category>
		<category><![CDATA[Stock Matlab function]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Pure Matlab]]></category>
		<category><![CDATA[Toolbar]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=8723</guid>

					<description><![CDATA[<p>Matlab R2018b added default axes mouse interactivity at the expense of performance. Luckily, we can speed-up the default axes. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/improving-graphics-interactivity">Improving graphics interactivity</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/undocumented-hg2-graphics-events" rel="bookmark" title="Undocumented HG2 graphics events">Undocumented HG2 graphics events </a> <small>Matlab's new HG2 graphics engine includes many new undocumented events that could be used in various ways. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/handle-graphics-behavior" rel="bookmark" title="Handle Graphics Behavior">Handle Graphics Behavior </a> <small>HG behaviors are an important aspect of Matlab graphics that enable custom control of handle functionality. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/improving-save-performance" rel="bookmark" title="Improving save performance">Improving save performance </a> <small>There are many different ways of improving Matlab's standard save function performance. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/waterloo-graphics" rel="bookmark" title="Waterloo graphics">Waterloo graphics </a> <small>Waterloo is an open-source library that can significantly improve Matlab GUI. ...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>Matlab release R2018b added the concept of <a href="https://undocumentedmatlab.com/articles/reverting-axes-controls-in-figure-toolbar" target="_blank">axes-specific toolbars</a> and default <a href="https://www.mathworks.com/help/matlab/creating_plots/control-axes-interactions.html" rel="nofollow" target="_blank">axes mouse interactivity</a>. <span class="alignright"><img decoding="async" src="https://undocumentedmatlab.com/images/speedometer4d_200x200.gif" alt="Accelerating MATLAB Performance" title="Accelerating MATLAB Performance" width="200" height="200" /></span> Plain 2D plot axes have the following default interactions enabled by default: <a href="https://www.mathworks.com/help/matlab/ref/matlab.graphics.interaction.interactions.paninteraction.html" rel="nofollow" target="_blank">PanInteraction</a>, <a href="https://www.mathworks.com/help/matlab/ref/matlab.graphics.interaction.interactions.zoominteraction.html" rel="nofollow" target="_blank">ZoomInteraction</a>, <a href="https://www.mathworks.com/help/matlab/ref/matlab.graphics.interaction.interactions.datatipinteraction.html" rel="nofollow" target="_blank">DataTipInteraction</a> and <a href="https://www.mathworks.com/help/matlab/ref/matlab.graphics.interaction.interactions.rulerpaninteraction.html" rel="nofollow" target="_blank">RulerPanInteraction</a>.</p>
<p>Unfortunately, I find that while the default interactions set is much more useful than the non-interactive default axes behavior in R2018a and earlier, it could still be improved in two important ways:</p>
<ol>
<li><b>Performance</b> &#8211; Matlab&#8217;s builtin Interaction objects are very inefficient. In cases of multiple overlapping axes (which is very common in multi-tab GUIs or cases of various types of axes), instead of processing events for just the top visible axes, they process all the enabled interactions for *all* axes (including non-visible ones!). This is particularly problematic with the default DataTipInteraction &#8211; it includes a <code>Linger</code> object whose apparent purpose is to detect when the mouse lingers for enough time on top of a chart object, and displays a data-tip in such cases. Its internal code is both inefficient and processed multiple times (for each of the axes), as can be seen via a profiling session.</li>
<li><b>Usability</b> &#8211; In my experience, <a href="https://www.mathworks.com/help/matlab/ref/matlab.graphics.interaction.interactions.regionzoominteraction.html" rel="nofollow" target="_blank">RegionZoomInteraction</a> (which enables defining a region zoom-box via click-&#038;-drag) is usually much more useful than PanInteraction for most plot types. ZoomInteraction, which is enabled by default only enables zooming-in and -out using the mouse-wheel, which is much less useful and more cumbersome to use than RegionZoomInteraction. The panning functionality can still be accessed interactively with the mouse by dragging the X and Y rulers (ticks) to each side.</li>
</ol>
<p>For these reasons, I typically use the following function whenever I create new axes, to replace the default sluggish DataTipInteraction and PanInteraction with RegionZoomInteraction:<br />
<span id="more-10306"></span></p>
<pre lang="matlab">
function axDefaultCreateFcn(hAxes, ~)
    try
        hAxes.Interactions = [zoomInteraction regionZoomInteraction rulerPanInteraction];
        hAxes.Toolbar = [];
    catch
        % ignore - old Matlab release
    end
end
</pre>
<p>The purpose of these two axes property changes shall become apparent below.<br />
This function can either be called directly (<code>axDefaultCreateFcn(hAxes</code>), or as part of the containing figure&#8217;s creation script to ensure than any axes created in this figure has this fix applied:</p>
<pre lang="matlab">
set(hFig,'defaultAxesCreateFcn',@axDefaultCreateFcn);
</pre>
<h3 id="testing">Test setup</h3>
<p><figure style="width: 268px" class="wp-caption alignright"><img fetchpriority="high" decoding="async" src="https://undocumentedmatlab.com/images/Axes_Interactivity.png" alt="Figure with default axes toolbar and interactivity" title="Figure with default axes toolbar and interactivity" width="268" height="200" /><figcaption class="wp-caption-text">Figure with default axes toolbar and interactivity</figcaption></figure> To test the changes, let&#8217;s prepare a figure with 10 tabs, with 10 overlapping panels and a single axes in each tab:</p>
<pre lang="matlab">
hFig = figure('Pos',[10,10,400,300]);
hTabGroup = uitabgroup(hFig);
for iTab = 1 : 10
    hTab = uitab(hTabGroup, 'title',num2str(iTab));
    hPanel = uipanel(hTab);
    for iPanel = 1 : 10
        hPanel = uipanel(hPanel);
    end
    hAxes(iTab) = axes(hPanel); %see MLint note below
    plot(hAxes(iTab),1:5,'-ob');
end
drawnow
</pre>
<p style="padding-left: 20px; margin-top: -15px;"><i><font size=-1>p.s. &#8211; there&#8217;s a incorrect MLint (Code Analyzer) warning in line 9 about the call to axes(hPanel) being inefficient in a loop. Apparently, MLint incorrectly parses this function call as a request to make the axes in-focus, rather than as a request to create the axes in the specified hPanel parent container. We can safely ignore this warning.</font></i></p>
<p>Now let&#8217;s create a run-time test script that simulates 2000 mouse movements using <a href="https://undocumentedmatlab.com/articles/gui-automation-robot" target="_blank">java.awt.Robot</a>:</p>
<pre lang="matlab">
tic
monitorPos = get(0,'MonitorPositions');
y0 = monitorPos(1,4) - 200;
robot = java.awt.Robot;
for iEvent = 1 : 2000
    robot.mouseMove(150, y0+mod(iEvent,100));
    drawnow
end
toc
</pre>
<p>This takes ~45 seconds to run on my laptop: ~23ms per mouse movement on average, with noticeable &#8220;linger&#8221; when the mouse pointer is near the plotted data line. Note that this figure is extremely simplistic &#8211; In a real-life program, the mouse events processing lag the mouse movements, making the GUI far more sluggish than the same GUI on R2018a or earlier. In fact, in one of my more complex GUIs, the entire GUI and Matlab itself came to a standstill that required killing the Matlab process, just by moving the mouse for several seconds.</p>
<p>Notice that at any time, only a single axes is actually visible in our test setup. The other 9 axes are not visible although their <b>Visible</b> property is <code>'on'</code>. Despite this, when the mouse moves within the figure, these other axes unnecessarily process the mouse events.</p>
<h3 id="interactions">Changing the default interactions</h3>
<p>Let&#8217;s modify the axes creation script as I mentioned above, by changing the default interactions (note the highlighted code addition):</p>
<pre lang="matlab" highlight="11">
hFig = figure('Pos',[10,10,400,300]);
hTabGroup = uitabgroup(hFig);
for iTab = 1 : 10
    hTab = uitab(hTabGroup, 'title',num2str(iTab));
    hPanel = uipanel(hTab);
    for iPanel = 1 : 10
        hPanel = uipanel(hPanel);
    end
    hAxes(iTab) = axes(hPanel);
    plot(hAxes(iTab),1:5,'-ob');
    hAxes(iTab).Interactions = [zoomInteraction regionZoomInteraction rulerPanInteraction];
end
drawnow
</pre>
<p>The test script now takes only 12 seconds to run &#8211; 4x faster than the default and yet IMHO with better interactivity (using RegionZoomInteraction).</p>
<h3 id="Toolbar">Effects of the axes toolbar</h3>
<p>The axes-specific toolbar, another innovation of R2018b, does not just have interactivity aspects, which are by themselves <a href="https://undocumentedmatlab.com/articles/reverting-axes-controls-in-figure-toolbar" target="_blank">much-contested</a>. A much less discussed aspect of the axes toolbar is that it degrades the overall performance of axes. The reason is that the axes toolbar&#8217;s transparency, visibility, background color and contents continuously update whenever the mouse moves within the axes area.</p>
<p>Since we have set up the default interactivity to a more-usable set above, and since we can replace the axes toolbar with figure-level toolbar controls, we can simply delete the axes-level toolbars for even more-improved performance:</p>
<pre lang="matlab" highlight="12">
hFig = figure('Pos',[10,10,400,300]);
hTabGroup = uitabgroup(hFig);
for iTab = 1 : 10
    hTab = uitab(hTabGroup, 'title',num2str(iTab));
    hPanel = uipanel(hTab);
    for iPanel = 1 : 10
        hPanel = uipanel(hPanel);
    end
    hAxes(iTab) = axes(hPanel);
    plot(hAxes(iTab),1:5,'-ob');
    hAxes(iTab).Interactions = [zoomInteraction regionZoomInteraction rulerPanInteraction];
    hAxes(iTab).Toolbar = [];
end
drawnow
</pre>
<p>This brings the test script&#8217;s run-time down to 6 seconds &#8211; <b>7x faster than the default run-time</b>. At ~3ms per mouse event, the GUI is now as performant and snippy as in R2018a, even with the new interactive mouse actions of R2018b active.</p>
<h3 id="Conclusions">Conclusions</h3>
<p>MathWorks definitely did not intend for this slow-down aspect, but it is an unfortunate by-product of the choice to auto-enable DataTipInteraction and of its sub-optimal implementation. Perhaps this side-effect was never noticed by MathWorks because the testing scripts probably had only a few axes in a very simple figure &#8211; in such a case the performance lags are very small and might have slipped under the radar. But I assume that many real-life complex GUIs will display significant lags in R2018b and newer Matlab releases, compared to R2018a and earlier releases. I assume that such users will be surprised/dismayed to discover that in R2018b their GUI not only interacts differently but also runs slower, although the program code has not changed.</p>
<p>One of the common claims that I often hear against using undocumented Matlab features is that the program might break in some future Matlab release that would not support some of these features. But users certainly do not expect that their programs might break in new Matlab releases when they only use documented features, as in this case. IMHO, this case (and others over the years) demonstrates that using undocumented features is usually not much riskier than using the standard documented features with regards to future compatibility, making the risk/reward ratio more favorable. In fact, of the ~400 posts that I have published in the past decade (this blog is already 10 years old, time flies&#8230;), very few tips no longer work in the latest Matlab release. When such forward compatibility issues do arise, whether with fully-documented or undocumented features, we can often find workarounds as I have shown above.</p>
<p>If your Matlab program could use a performance boost, I would be happy to assist making your program faster and more responsive. Don&#8217;t hesitate to reach out to me for a consulting quote.</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/improving-graphics-interactivity">Improving graphics interactivity</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/undocumented-hg2-graphics-events" rel="bookmark" title="Undocumented HG2 graphics events">Undocumented HG2 graphics events </a> <small>Matlab's new HG2 graphics engine includes many new undocumented events that could be used in various ways. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/handle-graphics-behavior" rel="bookmark" title="Handle Graphics Behavior">Handle Graphics Behavior </a> <small>HG behaviors are an important aspect of Matlab graphics that enable custom control of handle functionality. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/improving-save-performance" rel="bookmark" title="Improving save performance">Improving save performance </a> <small>There are many different ways of improving Matlab's standard save function performance. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/waterloo-graphics" rel="bookmark" title="Waterloo graphics">Waterloo graphics </a> <small>Waterloo is an open-source library that can significantly improve Matlab GUI. ...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/improving-graphics-interactivity/feed</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Interesting Matlab puzzle &#8211; analysis</title>
		<link>https://undocumentedmatlab.com/articles/interesting-matlab-puzzle-analysis?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=interesting-matlab-puzzle-analysis</link>
					<comments>https://undocumentedmatlab.com/articles/interesting-matlab-puzzle-analysis#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Tue, 09 Apr 2019 11:52:00 +0000</pubDate>
				<category><![CDATA[Medium risk of breaking in future versions]]></category>
		<category><![CDATA[Undocumented feature]]></category>
		<category><![CDATA[Pure Matlab]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=8664</guid>

					<description><![CDATA[<p>Solution and analysis of a simple Matlab puzzle that leads to interesting insight on Matlab's parser. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/interesting-matlab-puzzle-analysis">Interesting Matlab puzzle &#8211; analysis</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/interesting-matlab-puzzle" rel="bookmark" title="Interesting Matlab puzzle">Interesting Matlab puzzle </a> <small>A simple Matlab puzzle that leads to interesting insight on Matlab's parser. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/interesting-uitree-utility" rel="bookmark" title="An interesting uitree utility">An interesting uitree utility </a> <small>ExploreStruct is a utility that shows how custom uitrees can be integrated in Matlab GUI...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/couple-of-bugs-and-workarounds" rel="bookmark" title="A couple of internal Matlab bugs and workarounds">A couple of internal Matlab bugs and workarounds </a> <small>A couple of undocumented Matlab bugs have simple workarounds. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/matlab-compiler-bug-and-workaround" rel="bookmark" title="Matlab compiler bug and workaround">Matlab compiler bug and workaround </a> <small>Both the Matlab compiler and the publish function have errors when parsing block-comments in Matlab m-code. ...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>Last week I presented a seemingly-innocent Matlab code snippet with several variants, and asked readers to speculate what its outcomes are, and why. Several readers were apparently surprised by the results. In today&#8217;s post, I offer my analysis of the puzzle.<br />
The original code snippet was this:</p>
<pre lang="matlab" highlight="3">
function test
    try
        if (false) or (true)
            disp('Yaba');
        else
            disp('Daba');
        end
    catch
        disp('Doo!');
    end
end
</pre>
<p>With the following variants for the highlighted line #3:</p>
<pre lang="matlab">
        if (false) or (true)     % variant #1 (original)
        if (true)  or (false)    % variant #2
        if (true)  or (10< 9.9)  % variant #3
        if  true   or  10< 9.9   % variant #4
        if 10> 9.9 or  10< 9.9   % variant #5
</pre>
<p><span id="more-10305"></span></p>
<h3 id="variant-1">Variant #1: if (false) or (true)</h3>
<p>The first thing to note is that <code>or</code> is a function and not an operator, unlike some other programming languages. Since this function immediately follows a condition (<code>true</code>), it is not considered a condition by its own, and is not parsed as a part of the "if" expression.<br />
In other words, as Roger Watt <a href="https://undocumentedmatlab.com/articles/interesting-matlab-puzzle#comment-471709" target="_blank">correctly stated</a>, line #3 is actually composed of two separate expressions: <code>if (false)</code> and <code>or(true)</code>. The code snippet can be represented in a more readable format as follows, where the executed lines are highlighted:</p>
<pre lang="matlab" highlight="1,5">
        if (false)
            or (true)
            disp('Yaba');
        else
            disp('Daba');
        end
</pre>
<p>Since the condition (<code>false</code>) is never true, the "if" branch of the condition is never executed; only the "else" branch is executed, displaying 'Daba' in the Matlab console. There is no parsing (syntactic) error so the code can run, and no run-time error so the "catch" block is never executed.<br />
Also note that despite the misleading appearance of line #3 in the original code snippet, the condition only contains a single condition (<code>false</code>) and therefore neither <a href="https://www.mathworks.com/help/matlab/ref/shortcircuitor.html" rel="nofollow" target="_blank">short-circuit evaluation</a> nor eager evaluation are relevant (they only come into play in expressions that contain 2+ conditions).<br />
As Rik Wisselink <a href="https://undocumentedmatlab.com/articles/interesting-matlab-puzzle#comment-471713" target="_blank">speculated</a> and Michelle Hirsch <a href="https://undocumentedmatlab.com/articles/interesting-matlab-puzzle#comment-472001" target="_blank">later confirmed</a>, Matlab supports placing an expression immediately following an "if" statement, on the same line, without needing to separate the statements with a new line or even a comma (although this is suggested by the Editor's <a href="https://undocumentedmatlab.com/articles/parsing-mlint-code-analyzer-output" target="_blank">Mlint/Code-Analyzer</a>). As Michelle mentioned, this is mainly to support backward-compatibility with old Matlab code, and is a discouraged programming practice. Over the years Matlab has made a gradual shift from being a very weakly-typed and loose-format language to a more strongly-typed one having stricter syntax. So I would not be surprised if one day in the future Matlab would prevent such same-line conditional statements, and force a new line or comma separator between the condition statement and the conditional branch statement.<br />
Note that the "if" conditional branch never executes, and in fact it is optimized away by the interpreter. Therefore, it does not matter that the "or" function call would have errored, since it is never evaluated.</p>
<h3 id="variant-2">Variant #2: if (true) or (false)</h3>
<p>In this variant, the "if" condition is always true, causing the top conditional branch to execute. This starts with a call to <code>or(false)</code>, which throws a run-time error because the or() function expects 2 input arguments and only one is supplied (as Chris Luengo was the <a href="https://undocumentedmatlab.com/articles/interesting-matlab-puzzle#comment-471677" target="_blank">first to note</a>). Therefore, execution jumps to the "catch" block and 'Doo!' is displayed in the Matlab console.<br />
In a more verbose manner, this is the code (executed lines highlighted):</p>
<pre lang="matlab" highlight="3-4,10">
function test
    try
        if (true)
            or (false)
            disp('Yaba');
        else
            disp('Daba');
        end
    catch
        disp('Doo!');
    end
end
</pre>
<h3 id="variant-3">Variant #3: if (true) or (10< 9.9)</h3>
<p>This is exactly the same as variant #2, since the condition <code>10&lt; 9.9</code> is the same as <code>false</code>. The parentheses around the condition ensure that it is treated as a single logical expression (that evaluates to <code>false</code>) rather than being treated as 2 separate arguments. Since the or() function expects 2 input args, a run-time error will be thrown, resulting in a display of 'Doo!' in the Matlab console.<br />
As Will correctly <a href="https://undocumentedmatlab.com/articles/interesting-matlab-puzzle#comment-471920" target="_blank">noted</a>, this variant is simply a red herring whose aim was to lead up to the following variant:</p>
<h3 id="variant-4">Variant #4: if true or 10&lt; 9.9</h3>
<p>At first glance, this variant looks exactly the same as variant #3, because parentheses around conditions are not mandatory in Matlab. In fact, <code>if a || b</code> is equivalent to (and in many cases more readable/maintainable than) <code>if (a) || (b)</code>. However, remember that "or" is not a logical operator but rather a function call (see variant #1 above). For this reason, the <code>if true or 10&lt; 9.9</code> statement is equivalent to the following:</p>
<pre lang="matlab">
        if true
            or 10< 9.9
            ...
</pre>
<p>Now, you might think that this will cause a run-time error just as before (variant #2), but take a closer look at the input to the or() function call: there are no parentheses and so the Matlab interpreter parses the rest of the line as space-separated command-line inputs to the or() function, which are parsed as strings. Therefore, the statement is in fact interpreted as follows:</p>
<pre lang="matlab">
        if true
            or('10<', '9.9')
            ...
</pre>
<p>This is a valid "or" statement that causes no run-time error, since the function receives 2 input arguments that happen to be 3-by-1 character arrays. 3 element-wise or are performed (<code>'1'||'9'</code> and so-on), based on the inputs' ASCII codes. So, the code is basically the same as:</p>
<pre lang="matlab">
        if true
            or([49,48,60], [57,46,57])  % =ASCII values of '10<','9.9'
            disp('Yaba');
</pre>
<p>Which results in the following output in the Matlab console:</p>
<pre lang="matlab">
ans =
  1×3 logical array
   1   1   1
Yaba
</pre>
<p>As Will noted, this variant was cunningly crafted so that the 2 input args to "or" would each have exactly the same number of chars, otherwise a run-time error would occur ("Matrix dimensions must agree", except for the edge case where one of the operands only has a single element). As Marshall <a href="https://undocumentedmatlab.com/articles/interesting-matlab-puzzle#comment-472722" target="_blank">noted</a>, Matlab syntax highlighting (in the Matlab console or editor) can aid us understand the parsing, by highlighting the or() inputs in purple color, indicating strings.</p>
<h3 id="variant-5">Variant #5: if 10&gt; 9.9 or 10&lt; 9.9</h3>
<p>This is another variant whose main aim is confusing the readers (sorry about that; well, not really...). This variant is exactly the same as variant #4, because (as noted above) Matlab conditions do not need to be enclosed by parentheses. But whereas <code>10&gt; 9.9</code> is a single scalar condition (that evaluates to <code>true</code>), <code>10&lt; 9.9</code> are in fact 2 separate 3-character string arguments to the "or" function. The end result is exactly the same as in variant #4.<br />
I hope you enjoyed this little puzzle. Back to serious business in the next post!</p>
<h3 id="USA">USA visit</h3>
<p>I will be travelling in the US (Boston, New York, Baltimore) in May/June 2019. Please let me know (altmany at gmail) if you would like to schedule a meeting or onsite visit for consulting/training, or perhaps just to explore the possibility of my professional assistance to your Matlab programming needs.</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/interesting-matlab-puzzle-analysis">Interesting Matlab puzzle &#8211; analysis</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/interesting-matlab-puzzle" rel="bookmark" title="Interesting Matlab puzzle">Interesting Matlab puzzle </a> <small>A simple Matlab puzzle that leads to interesting insight on Matlab's parser. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/interesting-uitree-utility" rel="bookmark" title="An interesting uitree utility">An interesting uitree utility </a> <small>ExploreStruct is a utility that shows how custom uitrees can be integrated in Matlab GUI...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/couple-of-bugs-and-workarounds" rel="bookmark" title="A couple of internal Matlab bugs and workarounds">A couple of internal Matlab bugs and workarounds </a> <small>A couple of undocumented Matlab bugs have simple workarounds. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/matlab-compiler-bug-and-workaround" rel="bookmark" title="Matlab compiler bug and workaround">Matlab compiler bug and workaround </a> <small>Both the Matlab compiler and the publish function have errors when parsing block-comments in Matlab m-code. ...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/interesting-matlab-puzzle-analysis/feed</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Interesting Matlab puzzle</title>
		<link>https://undocumentedmatlab.com/articles/interesting-matlab-puzzle?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=interesting-matlab-puzzle</link>
					<comments>https://undocumentedmatlab.com/articles/interesting-matlab-puzzle#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Sun, 31 Mar 2019 10:15:06 +0000</pubDate>
				<category><![CDATA[Medium risk of breaking in future versions]]></category>
		<category><![CDATA[Undocumented feature]]></category>
		<category><![CDATA[Pure Matlab]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=8614</guid>

					<description><![CDATA[<p>A simple Matlab puzzle that leads to interesting insight on Matlab's parser. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/interesting-matlab-puzzle">Interesting Matlab puzzle</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/interesting-matlab-puzzle-analysis" rel="bookmark" title="Interesting Matlab puzzle &#8211; analysis">Interesting Matlab puzzle &#8211; analysis </a> <small>Solution and analysis of a simple Matlab puzzle that leads to interesting insight on Matlab's parser. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/interesting-uitree-utility" rel="bookmark" title="An interesting uitree utility">An interesting uitree utility </a> <small>ExploreStruct is a utility that shows how custom uitrees can be integrated in Matlab GUI...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/couple-of-bugs-and-workarounds" rel="bookmark" title="A couple of internal Matlab bugs and workarounds">A couple of internal Matlab bugs and workarounds </a> <small>A couple of undocumented Matlab bugs have simple workarounds. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/matlab-dde-support" rel="bookmark" title="Matlab DDE support">Matlab DDE support </a> <small>Windows DDE is an unsupported and undocumented feature of Matlab, that can be used to improve the work-flow in the Windows environment...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>Here&#8217;s a nice little puzzle that came to me from long-time Matlab veteran <a href="https://apjanke.net" rel="nofollow" target="_blank">Andrew Janke</a>:<br />
Without actually running the following code in Matlab, what do you expect its output to be? &#8216;Yaba&#8217;? &#8216;Daba&#8217;? perhaps &#8216;Doo!&#8217;? or maybe it won&#8217;t run at all because of a parsing error?</p>
<pre lang="matlab">
function test
    try
        if (false) or (true)
            disp('Yaba');
        else
            disp('Daba');
        end
    catch
        disp('Doo!');
    end
end
</pre>
<p>To muddy the waters a bit, do you think that <a href="https://www.mathworks.com/help/matlab/ref/logicaloperatorsshortcircuit.html" rel="nofollow" target="_blank">short-circuit evaluation</a> is at work here? or perhaps eager evaluation? or perhaps neither?<br />
Would the results be different if we switched the order of the conditional operands, i.e. <code>(true) or (false)</code> instead of <code>(false) or (true)</code>? if so, how and why?<br />
And does it matter if I used &#8220;<code>false</code>&#8221; or &#8220;<code>10&lt; 9.9</code>&#8221; as the &#8220;or&#8221; conditional?<br />
Are the parentheses around the conditions important? would the results be any different without these parentheses?<br />
In other words, how and why would the results change for the following variants?</p>
<pre lang="matlab">
        if (false) or (true)     % variant #1
        if (true)  or (false)    % variant #2
        if (true)  or (10< 9.9)  % variant #3
        if  true   or  10< 9.9   % variant #4
        if 10> 9.9 or  10< 9.9   % variant #5
</pre>
<p>Please post your thoughts in a comment below (expected results and the reason, for the main code snippet above and its variants), and then run the code. You might be surprised at the results, but not less importantly at the reasons. This deceivingly innocuous code snippet leads to interesting insight on Matlab's parser.<br />
Full marks will go to the first person who posts the correct results and reasoning/interpretation of the variants above (hint: it's not as trivial as it might look at first glance).<br />
<b><u>Addendum April 9, 2019</u></b>: I have now posted my solution/analysis of this puzzle <a href="https://undocumentedmatlab.com/articles/interesting-matlab-puzzle-analysis" target="_blank">here</a>.</p>
<h3 id="USA">USA visit</h3>
<p>I will be travelling in the US (Boston, New York, Baltimore) in May/June 2019. Please let me know (altmany at gmail) if you would like to schedule a meeting or onsite visit for consulting/training, or perhaps just to explore the possibility of my professional assistance to your Matlab programming needs.</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/interesting-matlab-puzzle">Interesting Matlab puzzle</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/interesting-matlab-puzzle-analysis" rel="bookmark" title="Interesting Matlab puzzle &#8211; analysis">Interesting Matlab puzzle &#8211; analysis </a> <small>Solution and analysis of a simple Matlab puzzle that leads to interesting insight on Matlab's parser. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/interesting-uitree-utility" rel="bookmark" title="An interesting uitree utility">An interesting uitree utility </a> <small>ExploreStruct is a utility that shows how custom uitrees can be integrated in Matlab GUI...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/couple-of-bugs-and-workarounds" rel="bookmark" title="A couple of internal Matlab bugs and workarounds">A couple of internal Matlab bugs and workarounds </a> <small>A couple of undocumented Matlab bugs have simple workarounds. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/matlab-dde-support" rel="bookmark" title="Matlab DDE support">Matlab DDE support </a> <small>Windows DDE is an unsupported and undocumented feature of Matlab, that can be used to improve the work-flow in the Windows environment...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/interesting-matlab-puzzle/feed</wfw:commentRss>
			<slash:comments>20</slash:comments>
		
		
			</item>
		<item>
		<title>Scrollable GUI panels</title>
		<link>https://undocumentedmatlab.com/articles/scrollable-gui-panels?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=scrollable-gui-panels</link>
					<comments>https://undocumentedmatlab.com/articles/scrollable-gui-panels#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Wed, 25 Jul 2018 09:50:31 +0000</pubDate>
				<category><![CDATA[GUI]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Medium risk of breaking in future versions]]></category>
		<category><![CDATA[Undocumented feature]]></category>
		<category><![CDATA[uipanel]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=7824</guid>

					<description><![CDATA[<p>Scrollbars can easily be added to Matlab panels, to enable scroll-panes of GUI controls and axes. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/scrollable-gui-panels">Scrollable GUI panels</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/tab-panels-uitab-and-relatives" rel="bookmark" title="Tab panels &#8211; uitab and relatives">Tab panels &#8211; uitab and relatives </a> <small>This article describes several undocumented Matlab functions that support tab-panels...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/syntax-highlighted-labels-panels" rel="bookmark" title="Syntax highlighted labels &amp; panels">Syntax highlighted labels &amp; panels </a> <small>Syntax-highlighted labels and edit-boxes can easily be displayed in Matlab GUI - this article explains how. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-matlab-uipanels" rel="bookmark" title="Customizing Matlab uipanels">Customizing Matlab uipanels </a> <small>Matlab uipanel controls can be customized using Java in ways that are impossible with plain Matlab. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/transparent-uipanels" rel="bookmark" title="Transparent uipanels">Transparent uipanels </a> <small>Matlab uipanels can be made transparent, for very useful effects. ...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>Matlab enables two types of GUI container types, via the <b>Units</b> property: fixed-size (<code>'pixels'</code>, <code>'chars'</code>, etc.) and flexible (<code>'normalized'</code>). In many cases, we need something in between: a panel that expands dynamically when its container grows (i.e., flexible/<code>normalized</code>), and displays scroll-bars when the container shrinks (i.e., fixed size, with a scrollable viewport). This functionality is relatively easy to achieve using a bit of undocumented magic powder. Today&#8217;s post will show how to do this with legacy (Java-based) figures, and next week&#8217;s post will do the same for web-based (JavaScript) uifigures.<br />
<center style="font-size:12px;"><img decoding="async" src="https://undocumentedmatlab.com/images/uipanel_animated.gif" alt="Scrollable Matlab GUI panel" title="Scrollable Matlab GUI panel" width="315" height="315" /><br />
Scrollable Matlab GUI panel</center><span id="more-7824"></span></p>
<h3 id="Description">Technical description</h3>
<p>The basic idea is that in HG2 (Matlab release R2014b onward), <i><b>uipanel</b></i>s are implemented using standard Java <code>JPanel</code> components. This enables all sorts of <a href="https://undocumentedmatlab.com/articles/customizing-matlab-uipanels" target="_blank">interesting customizations</a>. For the purposes of today&#8217;s discussion, the important thing to note is that the underlying <code>JPanel</code> object can be re-parented to reside inside a Java <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/scrollpane.html" rel="nofollow" target="_blank">JScrollPanel</a>.<br />
So, the idea is to get the Matlab panel&#8217;s underlying <code>JPanel</code> object reference, then embed it within a new <code>JScrollPanel</code> object that is placed at the exact same GUI coordinates as the original panel. The essential Matlab code snippet is this:</p>
<pre lang="matlab">
% Create the Matlab uipanel in the GUI
hPanel = uipanel(...); drawnow
% Get the panel's underlying JPanel object reference
jPanel = hPanel.JavaFrame.getGUIDEView.getParent;
% Embed the JPanel within a new JScrollPanel object
jScrollPanel = javaObjectEDT(javax.swing.JScrollPane(jPanel));
% Remove the JScrollPane border-line
jScrollPanel.setBorder([]);
% Place the JScrollPanel in same GUI location as the original panel
pixelpos = getpixelposition(hPanel);
hParent = hPanel.Parent;
[hjScrollPanel, hScrollPanel] = javacomponent(jScrollPanel, pixelpos, hParent);
hScrollPanel.Units = 'norm';
% Ensure that the scroll-panel and contained panel have linked visibility
hLink = linkprop([hPanel,hScrollPanel],'Visible');
setappdata(hPanel,'ScrollPanelVisibilityLink',hLink);
</pre>
<p>Note that this code will only work with panels created in legacy figures, not web-based uifigures (as I mentioned above, a similar solution for uifigures will be presented here next week).<br />
Also note that the new scroll-panel is created with <i><b>javaObjectEDT</b></i>, in order to avoid <a href="https://undocumentedmatlab.com/articles/matlab-and-the-event-dispatch-thread-edt" target="_blank">EDT synchronization problems</a><br />
We also want to link the visibility of the scroll-panel and its contained Matlab panel (<code>hPanel</code>), so that when the panel is set to be non-visible (<code>hPanel.Visible='off'</code>), the entire scroll-panel (scrollbars included) will become invisible, and vice-versa. We can do this by linking the <b>Visible</b> property of the Matlab panel and the scroll-panel container (<code>hScrollPanel</code>) using the <i><b>linkprop</b></i> function at the bottom of the script above. Note that we must persist the resulting <code>hLink</code> otherwise it becomes defunct &#8211; this is done by using <i><b>setappdata</b></i> to store the link in the panel (this way, when the panel is deleted, so does the link).</p>
<h3 id="Resize">Resizing the container</h3>
<p>The scroll-panel is created with a specific <code>pixelpos</code> location and size, and then its container is made to have <code>normalized</code> units. This ensures that when the container (<code>hParent</code>) grows, the scroll-panel grows as well, and no scrollbars appear (since they are not needed). But when the container shrinks in the X and/or Y direction, corresponding scrollbars appear as-needed. It sounds complicated, but it&#8217;s actually very intuitive, as the animated image above shows.<br />
When the container resizes, the displayed viewport image may &#8220;jump&#8221; sideways. To fix this we can attach a simple repaint callback function to the scroll-panel&#8217;s <b>SizeChangedFcn</b> property:</p>
<pre lang="matlab">
% Attach a repaint callback function
hScrollPanel.SizeChangedFcn = @repaintScrollPane;
% Define the callback function:
function repaintScrollPane(hScrollPanel, varargin)
    drawnow
    jScrollPanel = hScrollPanel.JavaPeer;
    offsetX = 0; %or: jScrollPanel.getHorizontalScrollBar.getValue;
    offsetY = 0; %or: jScrollPanel.getVerticalScrollBar.getValue;
    jOffsetPoint = java.awt.Point(offsetX, offsetY);
    jViewport = jScrollPanel.getViewport;
    jViewport.setViewPosition(jOffsetPoint);
    jScrollPanel.repaint;
end
</pre>
<p><center><figure style="width: 315px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/uipanel4b_cropped.gif" alt="Scrollbars automatically appear as-needed during resize" title="Scrollbars automatically appear as-needed during resize" width="315" height="183" /><figcaption class="wp-caption-text">Scrollbars automatically appear as-needed during resize</figcaption></figure></center></p>
<h3 id="ViewOffset">Viewport position/offset</h3>
<p>It would be convenient to have an easy-to-use <b>ViewOffset</b> property in the <code>hScrollPanel</code> object, in order to be able to programmatically query and set the current viewport position (i.e., scrollbars offset). We can add this property via the <i><b>addprop</b></i> function:</p>
<pre lang="matlab">
% Add a new Viewoffset property to hSCrollPanel object
hProp = addprop(hScrollPanel, 'ViewOffset');
hProp.GetMethod = @getViewOffset;  %viewOffset = getViewOffset(hScrollPanel)
hProp.SetMethod = @setViewOffset;  %setViewOffset(hScrollPanel, viewOffset)
% Getter method for the dynamic ViewOffset property
function viewOffset = getViewOffset(hScrollPanel, varargin)
    jScrollPanel = hScrollPanel.JavaPeer;
    jPoint = jScrollPanel.getViewport.getViewPosition;
    viewOffset = [jPoint.getX, jPoint.getY];
end
% Setter method for the dynamic ViewOffset property
function setViewOffset(hScrollPanel, viewOffset)
    jPoint = java.awt.Point(viewOffset(1), viewOffset(2));
    jScrollPanel = hScrollPanel.JavaPeer;
    jScrollPanel.getViewport.setViewPosition(jPoint);
    jScrollPanel.repaint;
end
</pre>
<p>This enables us to both query and update the scroll-panel&#8217;s view position &#8211; <code>[0,0]</code> means top-left corner (i.e., no scroll); <code>[12,34]</code> mean scrolling 12 to the right and 34 down:</p>
<pre lang="matlab">
>> offset = hScrollPanel.ViewOffset   % or: get(hScrollPanel,'ViewOffset')
offset =
     0     0
>> offset = hScrollPanel.ViewOffset   % or: get(hScrollPanel,'ViewOffset')
offset =
    12    34
% Scroll 30 pixels right, 50 pixels down
>> hScrollPanel.ViewOffset = [30,50];   % or: set(hScrollPanel,'ViewOffset',[30,50])
</pre>
<h3 id="attachScrollPanelTo">attachScrollPanelTo utility</h3>
<p>I have prepared a utility called <i><b>attachScrollPanelTo</b></i> (<a href="https://www.mathworks.com/matlabcentral/fileexchange/68325-attachscrollpanelto-add-scroll-panel-to-a-uipanel-or-axes" rel="nofollow" target="_blank">downloadable from the Matlab File Exchange</a>), which encapsulates all of the above, plus a few other features: inputs validation, <b>Viewport</b> property in the output scroll-pane object, automatic encasing in a new panel for input object that are not already a panel, etc. Feel free to download the utility, use it in your program, and modify the source-code to fit your needs. Here are some usage examples:</p>
<pre lang="matlab">
attachScrollPanelTo();  % display the demo
attachScrollPanelTo(hPanel) % place the specified hPanel in a scroll-panel
hScroll = attachScrollPanelTo(hPanel);
hScroll.ViewOffset = [30,50];  % set viewport offset (30px right, 50px down)
set(hScroll, 'ViewOffset',[30,50]);  % equivalent alternative
</pre>
<p>If you&#8217;d like me to add flare to your Matlab GUI, don&#8217;t hesitate to contact me on my <a href="https://undocumentedmatlab.com/consulting" target="_blank">Consulting page</a>.</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/scrollable-gui-panels">Scrollable GUI panels</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/tab-panels-uitab-and-relatives" rel="bookmark" title="Tab panels &#8211; uitab and relatives">Tab panels &#8211; uitab and relatives </a> <small>This article describes several undocumented Matlab functions that support tab-panels...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/syntax-highlighted-labels-panels" rel="bookmark" title="Syntax highlighted labels &amp; panels">Syntax highlighted labels &amp; panels </a> <small>Syntax-highlighted labels and edit-boxes can easily be displayed in Matlab GUI - this article explains how. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-matlab-uipanels" rel="bookmark" title="Customizing Matlab uipanels">Customizing Matlab uipanels </a> <small>Matlab uipanel controls can be customized using Java in ways that are impossible with plain Matlab. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/transparent-uipanels" rel="bookmark" title="Transparent uipanels">Transparent uipanels </a> <small>Matlab uipanels can be made transparent, for very useful effects. ...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/scrollable-gui-panels/feed</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Plot legend customization</title>
		<link>https://undocumentedmatlab.com/articles/plot-legend-customization?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=plot-legend-customization</link>
					<comments>https://undocumentedmatlab.com/articles/plot-legend-customization#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Thu, 12 Jul 2018 14:11:40 +0000</pubDate>
				<category><![CDATA[Handle graphics]]></category>
		<category><![CDATA[Medium risk of breaking in future versions]]></category>
		<category><![CDATA[Undocumented feature]]></category>
		<category><![CDATA[Pure Matlab]]></category>
		<category><![CDATA[Undocumented property]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=7744</guid>

					<description><![CDATA[<p>Matlab plot legends and their internal components can be customized using a variety of undocumented properties that are easily accessible. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/plot-legend-customization">Plot legend customization</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/plot-legend-title" rel="bookmark" title="Plot legend title">Plot legend title </a> <small>Titles to plot legends are easy to achieve in HG1 (R2014a or earlier), but much more difficult in HG2 (R2014b or newer). ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/plot-line-transparency-and-color-gradient" rel="bookmark" title="Plot line transparency and color gradient">Plot line transparency and color gradient </a> <small>Static and interpolated (gradient) colors and transparency can be set for plot lines in HG2. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/plot-markers-transparency-and-color-gradient" rel="bookmark" title="Plot markers transparency and color gradient">Plot markers transparency and color gradient </a> <small>Matlab plot-line markers can be customized to have transparency and color gradients. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/multi-column-grid-legend" rel="bookmark" title="Multi-column (grid) legend">Multi-column (grid) legend </a> <small>This article explains how to use undocumented axes listeners for implementing multi-column plot legends...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>Three years ago I <a href="/articles/plot-legend-title" target="_blank">explained</a> how we can use a couple of undocumented hidden properties of the legend in order to add a legend title (the legend object had no <b>Title</b> property back then &#8211; this was only added in a later Matlab release, perhaps as a result of my post). Today I will expand on that article by explaining the plot legend&#8217;s internal graphics hierarchy, how we can access each of these components, and then how this information could be used to customize the separate legend components. Note that the discussion today is only relevant for HG2 legends (i.e. R2014b or newer).<br />
Let&#8217;s start with a simple Matlab plot with a legend:</p>
<pre lang="matlab">
hold all;
hLine1 = plot(1:5);
hLine2 = plot(2:6);
hLegend = legend([hLine1,hLine2], 'Location','SouthEast');
hLegend.Title.String = 'MyLegend';
</pre>
<p><center><figure style="width: 210px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/legend_2018_1.gif" alt="Standard Matlab legend" title="Standard Matlab legend" width="210" height="145" /><figcaption class="wp-caption-text">Standard Matlab legend</figcaption></figure></center> This legend is composed of the following visible internal components, which can be customized separately:<br />
<center><img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/legend_2018_2.gif" alt="Matlab legend components" title="Matlab legend components" width="150" height="110" /></center><br />
<span id="more-7744"></span><br />
<!-- center>[caption id="" align="aligncenter" width="150" caption="Matlab legend components"]<img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/legend_2018_2.gif" alt="Matlab legend components" title="Matlab legend components" width="150" height="110" />[/caption]<img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/legend_2018_2.gif" alt="Matlab legend components" title="Matlab legend components" width="150" height="110" /></center --><br />
<!-- span class="alignright"><img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/legend_2018_2.gif" alt="Matlab legend components" title="Matlab legend components" width="150" height="110" /></span --></p>
<table>
<tr>
<th align="left">Id in screenshot</th>
<th align="left">Accessed via</th>
<th align="left">Object type</th>
<th align="left">Description</th>
<th align="left">Important properties</th>
</tr>
<tr>
<td>1</td>
<td><code>hLegend.Title</code></td>
<td><code>Text</code></td>
<td>Title of the legend</td>
<td><b>Visible</b>, <b>String</b>, <b>Color</b>, <b>FontSize</b>, <b>FontWeight</b>.</td>
</tr>
<tr>
<td>2</td>
<td><code>hLegend.TitleSeparator</code></td>
<td><code>LineStrip</code></td>
<td>Separator line between title and legend entries. Only appears when title is set.</td>
<td><b>Visible</b>, <b>LineStyle</b>, <b>LineWidth</b>, <b>ColorData</b> (4&#215;1 uint8)</td>
</tr>
<tr>
<td>3</td>
<td><code>hLegend.BoxEdge</code></td>
<td><code>LineLoop</code></td>
<td>Box (border) line around the entire legend (including title)</td>
<td><b>Visible</b>, <b>LineStyle</b>, <b>LineWidth</b>, <b>ColorData</b> (4&#215;1 uint8)</td</td>
</tr>
<tr>
<td>4</td>
<td><code>hLegend.EntryContainer.NodeChildren(2)</code></td>
<td><code>LegendEntry</code></td>
<td>Entry row in the legend, corresponding to <code>hLine1</code></td>
<td><b>Icon</b>, <b>Label</b>, <b>Object</b> (line object in main axes)</td>
</tr>
<tr>
<td>5</td>
<td><code>hLegend.EntryContainer.NodeChildren(1)</code></td>
<td><code>LegendEntry</code></td>
<td>Entry row in the legend, corresponding to <code>hLine2</code></td>
<td><b>Icon</b>, <b>Label</b>, <b>Object</b> (line object in main axes)</td>
</tr>
<tr>
<td>6</td>
<td><code>hLegend.EntryContainer.NodeChildren(1).Label</code></td>
<td><code>Text</code></td>
<td>Label of legend entry</td>
<td><b>Visible</b>, <b>String</b>, <b>Color</b>, <b>FontSize</b>, <b>FontWeight</b></td>
</tr>
<tr>
<td>7</td>
<td><code>hLegend.EntryContainer.NodeChildren(1).Icon</code></td>
<td><code>LegendIcon</code></td>
<td>Icon/marker of legend entry</td>
<td><b>Visible</b>, <b>Transform.Children.Children</b> (<code>LineStrip</code> object)</td>
</tr>
</table>
<p>A pivotal object of the legend group are the <code>LegendEntry</code> items, one per legend row:</p>
<pre lang="matlab">
>> hLegendEntry = hLegend.EntryContainer.NodeChildren(1);
>> get(hLegendEntry)
              Children: [3×1 Graphics]
                 Color: [0 0 0]
                 Dirty: 0
             FontAngle: 'normal'
              FontName: 'Helvetica'
              FontSize: 8
            FontWeight: 'normal'
      HandleVisibility: 'on'
               HitTest: 'on'
                  Icon: [1×1 LegendIcon]
                 Index: 0
           Interpreter: 'tex'
                 Label: [1×1 Text]
            LayoutInfo: [1×1 matlab.graphics.illustration.legend.ItemLayoutInfo]
                Legend: [1×1 Legend]
              Listener: [1×1 event.listener]
                Object: [1×1 Line]
               Overlay: [1×1 TriangleStrip]
          OverlayAlpha: 0.65
                Parent: [1×1 Group]
           PeerVisible: 'on'
         PickableParts: 'visible'
              Selected: 'off'
    SelectionHighlight: 'on'
               Visible: 'on'
       VisibleListener: [1×1 event.proplistener]
</pre>
<p>Each <code>LegendEntry</code> contains a back-reference to the original graphics object. In my example above, <code>hLegend.EntryContainer.NodeChildren(2).Object == hLine1</code>, and <code>hLegend.EntryContainer.NodeChildren(2).Object == hLine1</code>. Note how the default legend entries order is the reverse of the order of creation of the original graphics objects. Naturally, we can modify this order by creating the legend py passing it an array of handles that is ordered differently (see the documentation of the <i><b>legend</b></i> function).<br />
To get all the original graphic objects together, in a single array, we could use one of two mechanisms (note the different order of the returned objects):</p>
<pre lang="matlab">
% Alternative #1
>> [hLegend.EntryContainer.NodeChildren.Object]'
ans =
  2×1 Line array:
  Line    (data2)
  Line    (data1)
% Alternative #2
>> hLegend.PlotChildren
ans =
  2×1 Line array:
  Line    (data1)
  Line    (data2)
</pre>
<p>For some reason, accessing the displayed graphic line in <code>LegendEntry</code>&#8216;s <b>Icon</b> is not simple. For example, the <code>LineStrip</code> object that corresponds to <code>hLine2</code> can be gotten via:</p>
<pre lang="matlab">
hLegendEntry = hLegend.EntryContainer.NodeChildren(1);
hLegendIconLine = hLegendEntry.Icon.Transform.Children.Children;  % a LineStrip object in our example
</pre>
<p>I assume that this was done to enable non-standard icons for patches and other complex objects (in which case the displayed icon would not necessarily be a <code>LineStrip</code> object). In the case of a line with markers, for example, <code>hLegendIconLine</code> would be an array of 2 objects: a <code>LineStrip</code> object and a separate <code>Marker</code> object. Still, I think that a direct reference in a <code>hLegend.EntryContainer.NodeChildren(1).Icon</code> property would have helped in 99% of all cases, so that we wouldn&#8217;t need to pass through the <code>Transform</code> object.<br />
Anyway, once we have this object reference(s), we can modify its/their properties. In the case of a <code>LineStrip</code> this includes <b>LineStyle</b>, <b>LineWidth</b>, <b>ColorData</b> (4&#215;1 uint8), and <b>VertexData</b> (which controls position/length):</p>
<pre lang="matlab">
>> get(hLegendIconLine(end))  % LineStrip
          AlignVertexCenters: 'on'
             AmbientStrength: 0.3
                ColorBinding: 'object'
                   ColorData: [4×1 uint8]
                   ColorType: 'truecolor'
             DiffuseStrength: 0.6
            HandleVisibility: 'on'
                     HitTest: 'off'
                       Layer: 'middle'
                     LineCap: 'none'
                    LineJoin: 'round'
                   LineStyle: 'solid'
                   LineWidth: 0.5
               NormalBinding: 'none'
                  NormalData: []
                      Parent: [1×1 Group]
               PickableParts: 'visible'
    SpecularColorReflectance: 1
            SpecularExponent: 10
            SpecularStrength: 0.9
                   StripData: []
                     Texture: [0×0 GraphicsPlaceholder]
                  VertexData: [3×2 single]
               VertexIndices: []
                     Visible: 'on'
       WideLineRenderingHint: 'software'
</pre>
<p>and in the presense of markers:</p>
<pre lang="matlab">
>> get(hLegendIconLine(1))  % Marker
    EdgeColorBinding: 'object'
       EdgeColorData: [4×1 uint8]
       EdgeColorType: 'truecolor'
    FaceColorBinding: 'object'
       FaceColorData: []
       FaceColorType: 'truecolor'
    HandleVisibility: 'on'
             HitTest: 'off'
               Layer: 'middle'
           LineWidth: 0.5
              Parent: [1×1 Group]
       PickableParts: 'visible'
                Size: 6
         SizeBinding: 'object'
               Style: 'circle'
          VertexData: [3×1 single]
       VertexIndices: []
             Visible: 'on'
</pre>
<p>An additional undocumented legend property that is of interest is <b>ItemTokenSize</b>. This is a 2-element numeric array specifying the minimal size of the legend entries&#8217; icon and label. By default <code>hLegend.ItemTokenSize == [30,18]</code>, but we can either expand or shrink the icons/labels by setting different values. For example:</p>
<pre lang="matlab">hLegend.ItemTokenSize == [10,1];  % shrink legend icons and labels</pre>
<p>Note that regardless of the amount that we specify, the actual amount that will be used will be such that all legend labels appear.<br />
Fun: try playing with negative values for the icon and the label and see what happens 🙂<br />
Have you come across any other interesting undocumented aspect of Matlab legends? If so, then please share it in a comment below.</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/plot-legend-customization">Plot legend customization</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/plot-legend-title" rel="bookmark" title="Plot legend title">Plot legend title </a> <small>Titles to plot legends are easy to achieve in HG1 (R2014a or earlier), but much more difficult in HG2 (R2014b or newer). ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/plot-line-transparency-and-color-gradient" rel="bookmark" title="Plot line transparency and color gradient">Plot line transparency and color gradient </a> <small>Static and interpolated (gradient) colors and transparency can be set for plot lines in HG2. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/plot-markers-transparency-and-color-gradient" rel="bookmark" title="Plot markers transparency and color gradient">Plot markers transparency and color gradient </a> <small>Matlab plot-line markers can be customized to have transparency and color gradients. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/multi-column-grid-legend" rel="bookmark" title="Multi-column (grid) legend">Multi-column (grid) legend </a> <small>This article explains how to use undocumented axes listeners for implementing multi-column plot legends...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/plot-legend-customization/feed</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
			</item>
		<item>
		<title>Sliders in Matlab GUI &#8211; part 2</title>
		<link>https://undocumentedmatlab.com/articles/sliders-in-matlab-gui-part-2?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sliders-in-matlab-gui-part-2</link>
					<comments>https://undocumentedmatlab.com/articles/sliders-in-matlab-gui-part-2#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Thu, 05 Jul 2018 11:40:56 +0000</pubDate>
				<category><![CDATA[GUI]]></category>
		<category><![CDATA[Medium risk of breaking in future versions]]></category>
		<category><![CDATA[Semi-documented function]]></category>
		<category><![CDATA[Internal component]]></category>
		<category><![CDATA[Pure Matlab]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=7728</guid>

					<description><![CDATA[<p>Matlab contains a variety of ways to define/display slider controls in GUI windows. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/sliders-in-matlab-gui-part-2">Sliders in Matlab GUI &#8211; part 2</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/sliders-in-matlab-gui" rel="bookmark" title="Sliders in Matlab GUI">Sliders in Matlab GUI </a> <small>Professional-looking slider controls can easily be integrated in Matlab GUI. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/uiundo-matlab-undocumented-undo-redo-manager" rel="bookmark" title="uiundo &#8211; Matlab&#039;s undocumented undo/redo manager">uiundo &#8211; Matlab&#039;s undocumented undo/redo manager </a> <small>The built-in uiundo function provides easy yet undocumented access to Matlab's powerful undo/redo functionality. This article explains its usage....</small></li>
<li><a href="https://undocumentedmatlab.com/articles/matlab-and-the-event-dispatch-thread-edt" rel="bookmark" title="Matlab and the Event Dispatch Thread (EDT)">Matlab and the Event Dispatch Thread (EDT) </a> <small>The Java Swing Event Dispatch Thread (EDT) is very important for Matlab GUI timings. This article explains the potential pitfalls and their avoidance using undocumented Matlab functionality....</small></li>
<li><a href="https://undocumentedmatlab.com/articles/blurred-matlab-figure-window" rel="bookmark" title="Blurred Matlab figure window">Blurred Matlab figure window </a> <small>Matlab figure windows can be blurred using a semi-transparent overlaid window - this article explains how...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>Exactly 3 years ago I posted about various <a href="/articles/sliders-in-matlab-gui" target="_blank">alternatives for embedding sliders in Matlab GUI</a>. Today I will follow up on that post with a description of yet another undocumented builtin alternative &#8211; <i><b>controllib.widget.Slider</b></i>. A summary of the various alternatives can be seen in the following screenshot:<br />
<center><figure style="width: 344px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/sliders.gif" alt="Slider alternatives in Matlab GUI" title="Slider alternatives in Matlab GUI" width="344" height="303" /><figcaption class="wp-caption-text">Slider alternatives in Matlab GUI</figcaption></figure></center><br />
The <i><b>controllib.widget.Slider</b></i> component is a class in Matlab&#8217;s internal <code>controllib</code> package (last week I discussed a different utility function in this package, <a href="/articles/string-char-compatibility" target="_blank"><i><b>controllib.internal.util.hString2Char</b></i></a>).<br />
<span id="more-7728"></span><br />
<i><b>controllib.widget.Slider</b></i> accepts 3 input arguments: containing figure handle, position in pixels, and data values. For example:</p>
<pre lang="matlab">
>> hSlider = controllib.widget.Slider(gcf, [10,10,100,50], 5:25)
hSlider =
  Slider with properties:
        Data: [6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25]
       Index: 11
       Value: 15
    FontSize: 8
    Position: [10 10 100 50]
</pre>
<p>This creates an invisible axes at the specified figure location and displays graphic axes objects that provide the appearance of the slider. When you move the slider&#8217;s knob, or click its centerline or arrows (&#8220;Steppers&#8221;), the slider&#8217;s value changes accordingly.<br />
You can attach a callback function to the slider as follows:</p>
<pre lang="matlab">
myCallback = @(h,e) disp(h.Value);  % as an example
addlistener(hSlider, 'ValueChanged', myCallback);
</pre>
<p>Note that <i><b>controllib.widget.Slider</b></i> is based on pure-Matlab code and fully-supported functionality. The Matlab source code is available (<i>%matlabroot%/toolbox/shared/controllib/graphics/+controllib/+widget/Slider.m</i>) and quite readable. So while it does not actually work with the new web-based uifigures, is should be relatively easy to adapt the code so that this component could be displayed in such uifigures.<br />
Below is a script to recreate the screenshot above. Note the two alternative mechanisms for setting properties (Java setter-method notation, and HG set notation):</p>
<pre lang="matlab">
hFig = figure('Color','w');

% 1. controllib.widget.Slider
hSlider1 = controllib.widget.Slider(hFig, [10,10,100,50], 1:20);
hSlider1.Value = 12;

% 2. uicontrol
hSlider2 = uicontrol('style','slider', 'units','pixels', 'pos',[10,80,100,20], 'Min',0', 'Max',20, 'Value',12);

% 3. JScrollBar
jSlider3 = javaObjectEDT(javax.swing.JScrollBar);
jSlider3.setOrientation(jSlider3.HORIZONTAL);  % Java setter-method notation
set(jSlider3, 'VisibleAmount',1, 'Minimum',0, 'Maximum',20, 'Value',12);  % HG set notation
[hSlider3, hContainer3] = javacomponent(jSlider3, [10,130,100,20], hFig);

% 4. JSlider #1
jSlider4 = javaObjectEDT(javax.swing.JSlider(0,20,12))
jSlider4.setBackground(java.awt.Color.white);  % Java setter-method notation
set(jSlider4, 'MinorTickSpacing',1, 'MajorTickSpacing',4, 'SnapToTicks',true, 'PaintLabels',true);  % HG set notation
[hSlider4, hContainer4] = javacomponent(jSlider4, [10,180,100,30], hFig);

% 5. JSlider #2
jSlider5 = javaObjectEDT(javax.swing.JSlider(0,20,12))
jSlider5.setBackground(java.awt.Color.white);  % Java setter-method notation
jSlider5.setPaintTicks(true);
set(jSlider5, 'MinorTickSpacing',1, 'MajorTickSpacing',4, 'SnapToTicks',true, 'PaintLabels',true);  % HG set notation
[hSlider5, hContainer5] = javacomponent(jSlider5, [10,230,100,40], hFig);
</pre>
<p>For additional details regarding the other slider alternatives, please refer to <a href="/articles/sliders-in-matlab-gui" target="_blank">my earlier post</a> on this subject.<br />
Have you ever used another interesting utility or class in Matlab&#8217;s builtin packages? If so, please tell us about it in a comment below.</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/sliders-in-matlab-gui-part-2">Sliders in Matlab GUI &#8211; part 2</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/sliders-in-matlab-gui" rel="bookmark" title="Sliders in Matlab GUI">Sliders in Matlab GUI </a> <small>Professional-looking slider controls can easily be integrated in Matlab GUI. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/uiundo-matlab-undocumented-undo-redo-manager" rel="bookmark" title="uiundo &#8211; Matlab&#039;s undocumented undo/redo manager">uiundo &#8211; Matlab&#039;s undocumented undo/redo manager </a> <small>The built-in uiundo function provides easy yet undocumented access to Matlab's powerful undo/redo functionality. This article explains its usage....</small></li>
<li><a href="https://undocumentedmatlab.com/articles/matlab-and-the-event-dispatch-thread-edt" rel="bookmark" title="Matlab and the Event Dispatch Thread (EDT)">Matlab and the Event Dispatch Thread (EDT) </a> <small>The Java Swing Event Dispatch Thread (EDT) is very important for Matlab GUI timings. This article explains the potential pitfalls and their avoidance using undocumented Matlab functionality....</small></li>
<li><a href="https://undocumentedmatlab.com/articles/blurred-matlab-figure-window" rel="bookmark" title="Blurred Matlab figure window">Blurred Matlab figure window </a> <small>Matlab figure windows can be blurred using a semi-transparent overlaid window - this article explains how...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/sliders-in-matlab-gui-part-2/feed</wfw:commentRss>
			<slash:comments>9</slash:comments>
		
		
			</item>
		<item>
		<title>Auto-scale image colors</title>
		<link>https://undocumentedmatlab.com/articles/auto-scale-image-colors?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=auto-scale-image-colors</link>
					<comments>https://undocumentedmatlab.com/articles/auto-scale-image-colors#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Wed, 21 Feb 2018 18:06:23 +0000</pubDate>
				<category><![CDATA[Handle graphics]]></category>
		<category><![CDATA[Listeners]]></category>
		<category><![CDATA[Medium risk of breaking in future versions]]></category>
		<category><![CDATA[Undocumented feature]]></category>
		<category><![CDATA[HG2]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[Listener]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=7334</guid>

					<description><![CDATA[<p>Images can be automatically color-scaled for maximum resolution, using the undocumented MarkedClean  event. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/auto-scale-image-colors">Auto-scale image colors</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/image-easter-egg" rel="bookmark" title="Image Easter egg">Image Easter egg </a> <small>The default image presented by Matlab's image function has a very interesting undocumented story....</small></li>
<li><a href="https://undocumentedmatlab.com/articles/auto-completion-widget" rel="bookmark" title="Auto-completion widget">Auto-completion widget </a> <small>Matlab includes a variety of undocumented internal controls that can be used for an auto-completion component. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/persisting-transparent-colors-in-hg2" rel="bookmark" title="Persisting transparent colors in HG2">Persisting transparent colors in HG2 </a> <small>We can set semi- and fully-transparent colors in HG2 for multiple graphic objects, but making these settings stick is non-trivial. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/uitable-cell-colors" rel="bookmark" title="Uitable cell colors">Uitable cell colors </a> <small>A few Java-based customizations can transform a plain-looking data table into a lively colored one. ...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>I deal extensively in image processing in one of my consulting projects. The images are such that most of the interesting features are found in the central portion of the image. However, the margins of the image contain z-values that, while not interesting from an operational point-of-view, cause the displayed image&#8217;s color-limits (axes <b>CLim</b> property) to go wild. An image is worth a thousand words, so check the following raw image (courtesy of Flightware, Inc.), displayed by the following simple script:</p>
<pre lang="matlab">hImage = imagesc(imageData); colormap(gray); colorbar;</pre>
<p><center><figure style="width: 400px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/baseline2_1.png" alt="Raw image with default Matlab CLim" title="Raw image with default Matlab CLim" width="400" height="299" /><figcaption class="wp-caption-text">Raw image with default Matlab CLim</figcaption></figure></center></p>
<h3 id="rescale">Rescaling the axes color-limits</h3>
<p>As you can see, this image is pretty useless for human-eye analysis. The reason is that while all of the interesting features in the central portion of the image have a z-value of ~-6, the few pixels in the margins that have a z-value of 350+ screw up the color limits and ruin the perceptual resolution (image contrast). We could of course start to guess (or <i><b>histogram</b></i> the z-values) to get the interesting color-limit range, and then manually set <code>hAxes.CLim</code> to get a much more usable image:</p>
<pre lang="matlab">hAxes = hImage.Parent; hAxes.CLim = [-7.5,-6];</pre>
<p><center><figure style="width: 400px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/static_1.png" alt="Raw image with a custom CLim" title="Raw image with a custom CLim" width="400" height="299" /><figcaption class="wp-caption-text">Raw image with a custom CLim</figcaption></figure></center></p>
<h3 id="autoscale">Auto-scaling the axes color-limits</h3>
<p>Since the z-values range and distribution changes between different images, it would be better to automatically scale the axes color-limits based on an analysis of the image. A very simple technique for doing this is to take the 5%,95% or 10%,90% percentiles of the data, clamping all outlier data pixels to the extreme colors. If you have the Stats Toolbox you can use the <i><b>prctile</b></i> function for this, but if not (or even if you do), here&#8217;s a very fast alternative that automatically scales the axes color limits based on the specified threshold (a fraction between 0-0.49):<br />
<span id="more-7334"></span></p>
<pre lang="matlab">
% Rescale axes CLim based on displayed image portion's CData
function rescaleAxesClim(hImage, threshold)
    % Get the displayed image portion's CData
    CData = hImage.CData;
    hAxes = hImage.Parent;
    XLim = fix(hAxes.XLim);
    YLim = fix(hAxes.YLim);
    rows = min(max(min(YLim):max(YLim),1),size(CData,1)); % visible portion
    cols = min(max(min(XLim):max(XLim),1),size(CData,2)); % visible portion
    CData = CData(unique(rows),unique(cols));
    CData = CData(:);  % it's easier to work with a 1d array
    % Find the CLims from this displayed portion's CData
    CData = sort(CData(~isnan(CData)));  % or use the Stat Toolbox's prctile()
    thresholdVals = [threshold, 1-threshold];
    thresholdIdxs = fix(numel(CData) .* thresholdVals);
    CLim = CData(thresholdIdxs);
    % Update the axes
    hAxes.CLim = CLim;
end
</pre>
<p>Note that a threshold of 0 uses the full color range, resulting in no <b>CLim</b> rescaling at all. At the other extreme, a threshold approaching 0.5 reduces the color-range to a single value, basically reducing the image to an unusable B/W (rather than grayscale) image. Different images might require different thresholds for optimal contrast. I believe that a good starting point for the threshold is a value of 0.10, which corresponds to the 10-90% range of <b>CData</b> values.</p>
<h3 id="dynamic">Dynamic auto-scaling of axes color-limits</h3>
<p>This is very nice for the initial image display, but if we zoom-in, or pan a sub-image around, or update the image in some way, we would need to repeat calling this <i>rescaleAxesClim()</i> function every time the displayed image portion changes, otherwise we might still get unusable images. For example, if we zoom into the image above, we will see that the color-limits that were useful for the full image are much less useful on the local sub-image scale. The first (left) image uses the static custom color limits [-7.5,-6] above (i.e., simply zooming-in on that image, without modifying <b>CLim</b> again); the second (right) image is the result of repeating the call to <i>rescaleAxesClim()</i>, which improves the image contrast:<br />
<center><figure style="width: 400px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/static_4.png" alt="Zoomed-in image with a custom static CLim" title="Zoomed-in image with a custom static CLim" width="400" height="299" /><figcaption class="wp-caption-text">Zoomed-in image with a custom static CLim</figcaption></figure> <figure style="width: 400px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/dynamic_4.png" alt="Zoomed-in image with a re-applied custom CLim" title="Zoomed-in image with a re-applied custom CLim" width="400" height="299" /><figcaption class="wp-caption-text">Zoomed-in image with a re-applied custom CLim</figcaption></figure> </center><br />
We could in theory attach the <i>rescaleAxesClim()</i> function as a callback to the <i><b>zoom</b></i> and <i><b>pan</b></i> functions (that provide such callback hooks). However, we would still need to remember to manually call this function whenever we modify the image or its containing axes programmatically.<br />
A much simpler way is to attach our <i>rescaleAxesClim()</i> function as a callback to the image&#8217;s undocumented <a href="/articles/undocumented-hg2-graphics-events" target="_blank"><b>MarkedClean</b> event</a>:</p>
<pre lang="matlab">
% Instrument image: add a listener callback to rescale upon any image update
addlistener(hImage, 'MarkedClean', @(h,e)rescaleAxesClim(hImage,threshold));
</pre>
<p>In order to avoid callback recursion (potentially caused by modifying the axes <b>CLim</b> within the callback), we need to add a bit of code to the callback that prevents recursion/reentrancy (<a href="/articles/controlling-callback-re-entrancy" target="_blank">details</a>). Here&#8217;s one simple way to do this:</p>
<pre lang="matlab">
% Rescale axes CLim based on displayed image portion's CData
function rescaleAxesClim(hImage, threshold)
    % Check for callback reentrancy
    inCallback = getappdata(hImage, 'inCallback');
    if ~isempty(inCallback), return, end
    try
        setappdata(hImage, 'inCallback',1);  % prevent reentrancy
        % Get the displayed image portion's CData
        ...  (copied from above)
        % Update the axes
        hAx.CLim = CLim;
        drawnow; pause(0.001);  % finish all graphic updates before proceeding
    catch
    end
    setappdata(hImage, 'inCallback',[]);  % reenable this callback
end
</pre>
<p>The result of this dynamic automatic color-scaling can be seen below:<br />
<center><figure style="width: 400px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/dynamic_animated.gif" alt="Zoomed-in image with dynamic CLim" title="Zoomed-in image with dynamic CLim" width="400" height="299" /><figcaption class="wp-caption-text">Zoomed-in image with dynamic CLim</figcaption></figure></center></p>
<h3 id="autoScaleImageCLim">autoScaleImageCLim utility</h3>
<p>I have created a small utility called <i><b>autoScaleImageCLim</b></i>, which includes all the above, and automatically sets the specified input image(s) to use auto color scaling. Feel free to download this utility from <a href="https://www.mathworks.com/matlabcentral/fileexchange/66148-autoscaleimageclim" rel="nofollow" target="_blank">the Matlab File Exchange</a>. Here are a few usage examples:</p>
<pre lang="matlab">
autoScaleImageCLim()           % auto-scale the current axes' image
autoScaleImageCLim(hImage,5)   % auto-scale image using 5%-95% CData limits
autoScaleImageCLim(hImage,.07) % auto-scale image using 7%-93% CData limits
</pre>
<p>(note that the <code>hImage</code> input parameter can be an array of image handles)<br />
Hopefully one day the so-useful <b>MarkedClean</b> event will become a documented and fully-supported event for all HG objects in Matlab, so that we won&#8217;t need to worry that it might not be supported by some future Matlab release&#8230;</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/auto-scale-image-colors">Auto-scale image colors</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/image-easter-egg" rel="bookmark" title="Image Easter egg">Image Easter egg </a> <small>The default image presented by Matlab's image function has a very interesting undocumented story....</small></li>
<li><a href="https://undocumentedmatlab.com/articles/auto-completion-widget" rel="bookmark" title="Auto-completion widget">Auto-completion widget </a> <small>Matlab includes a variety of undocumented internal controls that can be used for an auto-completion component. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/persisting-transparent-colors-in-hg2" rel="bookmark" title="Persisting transparent colors in HG2">Persisting transparent colors in HG2 </a> <small>We can set semi- and fully-transparent colors in HG2 for multiple graphic objects, but making these settings stick is non-trivial. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/uitable-cell-colors" rel="bookmark" title="Uitable cell colors">Uitable cell colors </a> <small>A few Java-based customizations can transform a plain-looking data table into a lively colored one. ...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/auto-scale-image-colors/feed</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Customizing histogram plots</title>
		<link>https://undocumentedmatlab.com/articles/customizing-histogram-plots?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=customizing-histogram-plots</link>
					<comments>https://undocumentedmatlab.com/articles/customizing-histogram-plots#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Wed, 17 Jan 2018 20:41:15 +0000</pubDate>
				<category><![CDATA[Handle graphics]]></category>
		<category><![CDATA[Medium risk of breaking in future versions]]></category>
		<category><![CDATA[Stock Matlab function]]></category>
		<category><![CDATA[Undocumented feature]]></category>
		<category><![CDATA[HG2]]></category>
		<category><![CDATA[Pure Matlab]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=7292</guid>

					<description><![CDATA[<p>Basic bar charts and histogram plots can be customized in important aspects. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/customizing-histogram-plots">Customizing histogram plots</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/customizing-contour-plots" rel="bookmark" title="Customizing contour plots">Customizing contour plots </a> <small>Contour labels, lines and fill patches can easily be customized in Matlab HG2. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-contour-plots-part2" rel="bookmark" title="Customizing contour plots part 2">Customizing contour plots part 2 </a> <small>Matlab contour labels' color and font can easily be customized. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-contour-plots-part-2" rel="bookmark" title="Customizing contour plots part 2">Customizing contour plots part 2 </a> <small>The contour lines of 3D Matlab plot can be customized in many different ways. This is the 2nd article on this issue. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-axes-tick-labels" rel="bookmark" title="Customizing axes tick labels">Customizing axes tick labels </a> <small>Multiple customizations can be applied to tick labels. ...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>Earlier today, I was given the task of displaying a histogram plot of a list of values. In today&#8217;s post, I will walk through a few customizations that can be done to bar plots and histograms in order to achieve the desired results.<br />
We start by binning the raw data into pre-selected bins. This can easily be done using the builtin <i><b>histc</b></i> (deprecated) or <i><b>histcounts</b></i> functions. We can then use the <a href="https://www.mathworks.com/help/matlab/ref/bar.html" rel="nofollow" target="_blank"><i><b>bar</b></i> function</a> to plot the results:</p>
<pre lang="matlab">
[binCounts, binEdges] = histcounts(data);
hBars = bar(hAxes, binEdges(1:end-1), binCounts);
</pre>
<p><center><figure style="width: 400px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/histogram1.png" alt="Basic histogram bar plot" title="Basic histogram bar plot" width="400" height="180" /><figcaption class="wp-caption-text">Basic histogram bar plot</figcaption></figure></center><br />
Let&#8217;s improve the appearance: <span id="more-7292"></span>In my specific case, the data was financial return (percentage) values, so let&#8217;s modify the x-label format accordingly and display a title. To make the labels and title more legible, we decrease the axes <b>FontSize</b> to 8 and remove the axes box:</p>
<pre lang="matlab">
hAxes = hBar.Parent;
xtickformat(hAxes, '%g%%');
title(hAxes, 'Distribution of total returns (monthly %)');
set(hAxes, 'FontSize',8, 'Box','off')
</pre>
<p><center><figure style="width: 400px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/histogram2.png" alt="Improved histogram bar plot" title="Improved histogram bar plot" width="400" height="180" /><figcaption class="wp-caption-text">Improved histogram bar plot</figcaption></figure></center><br />
So far nothing undocumented. Note that the <i><b>xtickformat/ytickformat</b></i> functions were only introduced in R2016b &#8211; for earlier Matlab releases <a href="/articles/setting-axes-tick-labels-format" target="_blank">see this post</a> (which does rely on undocumented aspects).<br />
Now, let&#8217;s use a couple of undocumented properties: to remove the excess white-space margin around the axes we&#8217;ll set the axes&#8217; <a href="/articles/axes-looseinset-property" target="_blank"><b>LooseInset</b> property</a>, and to remove the annoying white space between the tick labels and the X-axis we&#8217;ll set the <b>XRuler</b>&#8216;s <b>TickLabelGapOffset</b> property to -2 (default: +2):</p>
<pre lang="matlab">
set(hAxes, 'LooseInset',[0,0,0,0]);    % default = [.13,.11,.095,.075]
hAxes.XRuler.TickLabelGapOffset = -2;  % default = +2
</pre>
<p><center><figure style="width: 400px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/histogram3.png" alt="Even better histogram bar plot" title="Even better histogram bar plot" width="400" height="180" /><figcaption class="wp-caption-text">Even better histogram bar plot</figcaption></figure></center><br />
Note that I used the undocumented axes <b>XRuler</b> property instead of the axes&#8217; documented <a href="https://www.mathworks.com/help/matlab/ref/matlab.graphics.axis.axes-properties.html#prop_XAxis" rel="nofollow" target="_blank"><b>XAxis</b> property</a>, because <b>XAxis</b> is only available since R2015b, whereas <b>XRuler</b> (which points to the exact same object as <b>XAxis</b>) exists ever since R2014b, and so is better from a backward-compatibility standpoint. In either case, the ruler&#8217;s <b>TickLabelGapOffset</b> property is undocumented. Note that the ruler also contains another associated and undocumented <b>TickLabelGapMultiplier</b> property (default: 0.2), which I have not modified in this case.<br />
Now let&#8217;s take a look at the bin labels: The problem with the bar plot above is that it&#8217;s not intuitively clear whether the bin for &#8220;5%&#8221;, for example, includes data between 4.5-5.5 or between 5.0-6.0 (which is the correct answer). It would be nicer if the labels were matched to the actual bin edges. There are 3 basic ways to fix this:</p>
<ol>
<li>We could modify the bar plot axes tick values and labels, in essence &#8220;cheating&#8221; by moving the tick labels half a bin leftward of their tick values (don&#8217;t forget to add the extra tick label on the right):
<pre lang="matlab">
hAxes.XTick(end+1) = hAxes.XTick(end) + 1;  % extra tick label on the right
labels = hAxes.XTickLabels;       % preserve tick labels for later use below
hAxes.XTick = hAxes.XTick - 0.5;  % move tick labels 1/2 bin leftward
hAxes.XTickLabel = labels;        % restore pre-saved tick labels
hAxes.XLim = hAxes.XLim - 0.5;    % ...and align the XLim
</pre>
<p><center><figure style="width: 400px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/histogram4.png" alt="Improved labels" title="Improved labels" width="400" height="180" /><figcaption class="wp-caption-text">Improved labels</figcaption></figure></center>
</li>
<li>We could use the <i><b>bar</b></i> function&#8217;s optional <code>'histc'</code> flag, in order to display the bars in histogram mode. The problem in histogram mode is that while the labels are now placed correctly, the bars touch each other &#8211; I personally find distinct bars that are separated by a small gap easier to understand.
<pre lang="matlab">
hBars = bar(..., 'histc');
% [snip] - same customizations to hAxes as done above
</pre>
<p><center><figure style="width: 400px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/histogram5.png" alt="Basic histogram plot" title="Basic histogram plot" width="400" height="180" /><figcaption class="wp-caption-text">Basic histogram plot</figcaption></figure></center><br />
With the original bar chart we could use the built-in <b>BarWidth</b> to set the bar/gap width (default: 0.8 meaning a 10% gap on either side of the bar). Unfortunately, calling <i><b>bar</b></i> with <code>'hist'</code> or <code>'histc'</code> (i.e. histogram mode) results in a <code>Patch</code> (not <code>Bar</code>) object, and patches do not have a <b>BarWidth</b> property. However, we can modify the resulting patch vertices in order to achieve the same effect:</p>
<pre lang="matlab">
% Modify the patch vertices (5 vertices per bar, row-based)
hBars.Vertices(:,1) = hBars.Vertices(:,1) + 0.1;
hBars.Vertices(4:5:end,1) = hBars.Vertices(4:5:end,1) - 0.2;
hBars.Vertices(5:5:end,1) = hBars.Vertices(5:5:end,1) - 0.2;
% Align the bars & labels at the center of the axes
hAxes.XLim = hAxes.XLim + 0.5;
</pre>
<p>This now looks the same as option #1 above, except that the top-level handle is a <code>Patch</code> (not <code>Bar</code>) object. For various additional customizations, either <code>Patch</code> or <code>Bar</code> might be preferable, so you have a choice.<br />
<center><figure style="width: 400px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="https://undocumentedmatlab.com/images/histogram4.png" alt="Improved histogram plot" title="Improved histogram plot" width="400" height="180" /><figcaption class="wp-caption-text">Improved histogram plot</figcaption></figure></center>
</li>
<li>Lastly, we could have used the builtin <a href="https://www.mathworks.com/help/matlab/ref/histogram.html" rel="nofollow" target="_blank"><i><b>histogram</b></i> function</a> instead of <i><b>bar</b></i>. This function also displays a plot with touching bars, as above, using <code>Quadrilateral</code> objects (a close relative of <code>Patch</code>). The solution here is very similar to option #2 above, but we need to dig a bit harder to modify the patch faces, since their vertices is not exposed as a public property of the <code>Histogram</code> object. To modify the vertices, we first get the private <b>Face</b> property (<a href="/articles/accessing-private-object-properties" target="_blank">explanation</a>), and then modify its vertices, keeping in mind that in this specific case the bars have 4 vertices per bar and a different vertices matrix orientation:
<pre lang="matlab">
hBars = histogram(data, 'FaceAlpha',1.0, 'EdgeColor','none');
% [snip] - same customizations to hAxes as done above
% Get access to *ALL* the object's properties
oldWarn = warning('off','MATLAB:structOnObject');
warning off MATLAB:hg:EraseModeIgnored
hBarsStruct = struct(hBars);
warning(oldWarn);
% Modify the patch vertices (4 vertices per bar, column-based)
drawnow;  % this is important, won't work without this!
hFace = hBarsStruct.Face;  % a Quadrilateral object (matlab.graphics.primitive.world.Quadrilateral)
hFace.VertexData(1,:) = hFace.VertexData(1,:) + 0.1;
hFace.VertexData(1,3:4:end) = hFace.VertexData(1,3:4:end) - 0.2;
hFace.VertexData(1,4:4:end) = hFace.VertexData(1,4:4:end) - 0.2;
</pre>
</ol>
<p>In conclusion, there are many different ways to improve the appearance of charts in Matlab. Even if at first glance it may seem that some visualization function does not have the requested customization property or feature, a little digging will often find either a relevant undocumented property, or an internal object whose properties could be modified. If you need assistance with customizing your charts for improved functionality and appearance, then consider contacting me for a <a href="/consulting" target="_blank">consulting session</a>.</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/customizing-histogram-plots">Customizing histogram plots</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/customizing-contour-plots" rel="bookmark" title="Customizing contour plots">Customizing contour plots </a> <small>Contour labels, lines and fill patches can easily be customized in Matlab HG2. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-contour-plots-part2" rel="bookmark" title="Customizing contour plots part 2">Customizing contour plots part 2 </a> <small>Matlab contour labels' color and font can easily be customized. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-contour-plots-part-2" rel="bookmark" title="Customizing contour plots part 2">Customizing contour plots part 2 </a> <small>The contour lines of 3D Matlab plot can be customized in many different ways. This is the 2nd article on this issue. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-axes-tick-labels" rel="bookmark" title="Customizing axes tick labels">Customizing axes tick labels </a> <small>Multiple customizations can be applied to tick labels. ...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/customizing-histogram-plots/feed</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Runtime code instrumentation</title>
		<link>https://undocumentedmatlab.com/articles/runtime-code-instrumentation?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=runtime-code-instrumentation</link>
					<comments>https://undocumentedmatlab.com/articles/runtime-code-instrumentation#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Thu, 28 Sep 2017 13:36:17 +0000</pubDate>
				<category><![CDATA[Medium risk of breaking in future versions]]></category>
		<category><![CDATA[Stock Matlab function]]></category>
		<category><![CDATA[Undocumented feature]]></category>
		<category><![CDATA[File Exchange]]></category>
		<category><![CDATA[Pure Matlab]]></category>
		<category><![CDATA[Undocumented function]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=7063</guid>

					<description><![CDATA[<p>Conditional breakpoints can be used to instrument code with user-specified code. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/runtime-code-instrumentation">Runtime code instrumentation</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/parsing-mlint-code-analyzer-output" rel="bookmark" title="Parsing mlint (Code Analyzer) output">Parsing mlint (Code Analyzer) output </a> <small>The Matlab Code Analyzer (mlint) has a lot of undocumented functionality just waiting to be used. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/running-vb-code-in-matlab" rel="bookmark" title="Running VB code in Matlab">Running VB code in Matlab </a> <small>Matlab does not natively enable running VB code, but a nice trick enables us to do just that...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/couple-of-bugs-and-workarounds" rel="bookmark" title="A couple of internal Matlab bugs and workarounds">A couple of internal Matlab bugs and workarounds </a> <small>A couple of undocumented Matlab bugs have simple workarounds. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/controlling-plot-data-tips" rel="bookmark" title="Controlling plot data-tips">Controlling plot data-tips </a> <small>Data-tips are an extremely useful plotting tool that can easily be controlled programmatically....</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>I regularly follow the MathWorks <a href="https://blogs.mathworks.com/pick" rel="nofollow" target="_blank">Pick-of-the-Week (POTW) blog</a>. In a <a href="https://blogs.mathworks.com/pick/2017/08/11/trace-your-calls-to-your-methods" rel="nofollow" target="_blank">recent post</a>, Jiro Doke highlighted Per Isakson&#8217;s <a href="http://www.mathworks.com/matlabcentral/fileexchange/28929-tracer4m" rel="nofollow" target="_blank"><i><b>tracer4m</b></i></a> utility. Per is an accomplished Matlab programmer, who has a solid reputation in the Matlab user community for many years. His utility uses temporary conditional breakpoints to enable users to trace calls to their Matlab functions and class methods. This uses a little-known trick that I wish to highlight in this post.<br />
<center><figure style="width: 430px" class="wp-caption aligncenter"><a href="http://www.mathworks.com/matlabcentral/fileexchange/28929-tracer4m" rel="nofollow" target="_blank"><img decoding="async" alt="tracer4m utility uses conditional breakpoints that evaluate but never become live" src="https://www.mathworks.com/matlabcentral/mlc-downloads/downloads/submissions/28929/versions/3/screenshot.png" title="tracer4m utility uses conditional breakpoints that evaluate but never become live" width="430" hight="353"/></a><figcaption class="wp-caption-text">tracer4m utility uses conditional breakpoints that evaluate but never become live</figcaption></figure></center><br />
Matlab breakpoints are documented and supported functionality, and yet their documented use is typically focused at interactive programming in the Matlab editor, or as interactive commands that are entered in the Matlab console using the set of db* functions: <i><b>dbstop</b></i>, <i><b>dbclear</b></i>, <i><b>dbstatus</b></i>, <i><b>dbstack</b></i> etc. However, nothing prevents us from using these db* functions directly within our code.<br />
<span id="more-7063"></span><br />
For example, the <i><b>dbstack</b></i> function can help us diagnose the calling tree for the current function, in order to do action A if one of the calling ancestors was FunctionX, or to do action B otherwise (for example, to avoid nested recursions).<br />
Similarly, we could add a programmatic call to <i><b>dbstop</b></i> in order to stop at a certain code location downstream (for debugging), if a certain condition happens upstream.<br />
Per extended this idea very cleverly in <i><b>tracer4m</b></i>: conditional breakpoints evaluate a string in run-time: if the result is true (non-zero) then the code run is stopped at that location, but if it&#8217;s false (or zero) then the code run continues normally. To instrument calls to specific functions, Per created a function <code>tracer()</code> that logs the function call (using <i><b>dbstack</b></i>) and always returns the value <code>false</code>. He then dynamically created a string that contains a call to this new function and used the <i><b>dbstop</b></i> function to create a conditional breakpoint based on this function, something similar to this:</p>
<pre lang="matlab">dbstop('in', filename, 'at', location, 'if', 'tracer()');</pre>
<p>We can use this same technique for other purposes. For example, if we want to do some action (not necessarily log &#8211; perhaps do something else) when a certain code point is reached. The benefit here is that we don&#8217;t need to modify the code at all &#8211; we&#8217;re adding ad-hoc code pieces using the conditional breakpoint mechanism without affecting the source code. This is particularly useful when we do not have access to the source code (such as when it&#8217;s compiled or write-protected). All you need to do is to ensure that the instrumentation function always returns <code>false</code> so that the breakpoint does not become live and for code execution to continue normally.<br />
The <i><b>tracer4m</b></i> utility is quite sophisticated in the sense that it uses <i><b>mlint</b></i> and smart <i><b>regexp</b></i> to parse the code and know which functions/methods occur on which line numbers and have which type (<a href="/articles/parsing-mlint-code-analyzer-output" target="_blank">more details</a>). In this sense, Per used undocumented functionality. I&#8217;m certain that Jiro was not aware of the dependency on undocumented features when he posted about the utility, so please don&#8217;t take this to mean that Jiro or MathWorks officially support this or any other undocumented functionality. Undocumented aspects are often needed to achieve top functionality, and I&#8217;m happy that the POTW blog highlights utilities based on their importance and merit, even if they do happen to use some undocumented aspect.<br />
<i><b>tracer4m</b></i>&#8216;s code also contains references to the <a href="/articles/undocumented-profiler-options-part-3" target="_blank">undocumented profiler option <code>-history</code></a>, but this is not in fact used by the code itself, only in comments. I use this feature in my <a href="/articles/function-call-timeline-profiling" target="_blank">profile_history utility</a>, which displays the function call/timing history in an interactive GUI window. This utility complements <i><b>tracer4m</b></i> by providing a lot more information, but this can result in a huge amount of information for large and/or long-running programs. In addition, <i><b>tracer4m</b></i> has the benefit of only logging those functions/methods that the user finds useful, rather than all the function call, which enables easier debugging when the relevant code area is known. In short, I wish I had known about <i><b>tracer4m</b></i> when I created <i><b>profile_history</b></i>. Now that I know about it, maybe I&#8217;ll incorporate some of its ideas into <i><b>profile_history</b></i> in order to make it more useful. Perhaps another moral of this is that we should actively monitor the POTW blog, because true gems are quite often highlighted there.<br />
<center><a target="_blank" href="/articles/function-call-timeline-profiling"><img decoding="async" alt="Function call timeline profiling" src="https://undocumentedmatlab.com/images/profile_history.png" title="Function call timeline profiling" width="100%" style="max-width: 658px;" /></a><br />
Function call timeline profiling</center><br />
<!-- center>[caption id="" align="aligncenter" width="500" caption="Function call timeline profiling"]<a target="_blank" href="/articles/function-call-timeline-profiling"><img loading="lazy" decoding="async" alt="Function call timeline profiling" src="https://undocumentedmatlab.com/images/profile_history.png" title="Function call timeline profiling" width="500" height="410" /></a>[/caption]</center --><br />
For anyone who missed the announcement in my previous post, I&#8217;m hosting a series of live <a href="/articles/advanced-matlab-online-webinars" target="_blank">webinars on advanced Matlab topics</a> in the upcoming 2 weeks &#8211; I&#8217;ll be happy if you would join.</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/runtime-code-instrumentation">Runtime code instrumentation</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/parsing-mlint-code-analyzer-output" rel="bookmark" title="Parsing mlint (Code Analyzer) output">Parsing mlint (Code Analyzer) output </a> <small>The Matlab Code Analyzer (mlint) has a lot of undocumented functionality just waiting to be used. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/running-vb-code-in-matlab" rel="bookmark" title="Running VB code in Matlab">Running VB code in Matlab </a> <small>Matlab does not natively enable running VB code, but a nice trick enables us to do just that...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/couple-of-bugs-and-workarounds" rel="bookmark" title="A couple of internal Matlab bugs and workarounds">A couple of internal Matlab bugs and workarounds </a> <small>A couple of undocumented Matlab bugs have simple workarounds. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/controlling-plot-data-tips" rel="bookmark" title="Controlling plot data-tips">Controlling plot data-tips </a> <small>Data-tips are an extremely useful plotting tool that can easily be controlled programmatically....</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/runtime-code-instrumentation/feed</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>User-defined tab completions &#8211; take 2</title>
		<link>https://undocumentedmatlab.com/articles/user-defined-tab-completions-take-2?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=user-defined-tab-completions-take-2</link>
					<comments>https://undocumentedmatlab.com/articles/user-defined-tab-completions-take-2#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Wed, 12 Jul 2017 13:00:30 +0000</pubDate>
				<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Medium risk of breaking in future versions]]></category>
		<category><![CDATA[Undocumented feature]]></category>
		<category><![CDATA[Pure Matlab]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=6961</guid>

					<description><![CDATA[<p>Matlab has changed the mechanism that enables user-defined tab-completion of function inputs. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/user-defined-tab-completions-take-2">User-defined tab completions &#8211; take 2</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/setting-desktop-tab-completions" rel="bookmark" title="Setting desktop tab completions">Setting desktop tab completions </a> <small>The Matlab desktop's Command-Window tab-completion can be customized for user-defined functions...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/enabling-user-callbacks-during-zoom-pan" rel="bookmark" title="Enabling user callbacks during zoom/pan">Enabling user callbacks during zoom/pan </a> <small>Matlab zoom, pan and rotate3d modes hijack the user's figure callbacks, but this can be overridden. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/removing-user-preferences-from-deployed-apps" rel="bookmark" title="Removing user preferences from deployed apps">Removing user preferences from deployed apps </a> <small>An unsupported MathWorks Technical Solution explains how to remove private information from deployed (compiled) matlab applications. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/creating-a-simple-udd-class" rel="bookmark" title="Creating a simple UDD class">Creating a simple UDD class </a> <small>This article explains how to create and test custom UDD packages, classes and objects...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>Back in 2010, I posted about Matlab&#8217;s undocumented mechanism for <a href="/articles/setting-desktop-tab-completions" target="_blank">setting Matlab desktop tab-completions</a>. That mechanism used a couple of internal files (<i>TC.xml</i> and <i>TC.xsd</i>) to describe the various possible options that are auto-completed (or displayed in a small tooltip window) when the user clicks the &lt;Tab&gt; key on partially-entered function input parameters.<br />
<center><figure style="width: 408px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" alt="Using TabComplete for user-defined functions" src="https://undocumentedmatlab.com/images/tabcomplete.png" title="Using TabComplete for user-defined functions" width="408" height="147" /><figcaption class="wp-caption-text">Using TabComplete for user-defined functions</figcaption></figure></center><br />
Unfortunately, this mechanism apparently broke in R2016a and was replaced with a new mechanism, as explained below.<br />
The new mechanism relies on a file called <i>functionSignatures.json</i> which exists in every single folder that contains Matlab files that have functions whose input parameters ought to be tab-completable.<br />
The new mechanism offers far greater versatility and flexability in defining the input types and inter-relationsships compared to the old TC.*-based mechanism. Another important benefit is that we can now add custom user-defined <i>functionSignatures.json</i> files to our user folders, next to our m-files, without having to modify any Matlab system file.<br />
<span id="more-6961"></span><br />
Note that you may need to restart Matlab the first time that you create a <i>functionSignatures.json</i> file. But once it&#8217;s created, you can modify it within a Matlab session and the changes take effect immediately.<br />
Note: Credit for first posting about this new mechanism goes to <a href="https://www.mathworks.com/matlabcentral/answers/9046-autocomplete-of-filenames-for-function-input-params#answer_256591" rel="nofollow" target="_blank">Nicholas Mati</a>. I&#8217;ve known about this new mechanism for over a year, but I never found the time to write about it until now, so Nicholas gets credit for breaking the scoop. The discussion below uses and expands Nicholas&#8217; original post.</p>
<h3 id="syntax">Syntax</h3>
<p>The <i>functionSignatures.json</i> file has the general form:</p>
<pre lang="text">
{
	"FunctionName1":
	{
		"key1":"val1",
		"key2":"val2",
		"keyn":"valn"
	},
	"FunctionName2":
	{
		"key1":"val1",
		"key2":"val2",
		"keyn":"valn"
	}
}
</pre>
<p>A number of keys are supported including &#8220;<b>platform</b>&#8220;, &#8220;<b>setsAns</b>&#8220;, &#8220;<b>inputs</b>&#8220;, and &#8220;<b>outputs</b>&#8220;, although inputs and outputs are by far the most common (and presumably only inputs are relevant for tab-completion). These keys take an array of (or a single) object value(s). The objects typically take one of the following forms:</p>
<pre lang="text">
{"name":"variable_name", "kind":"kind_option", "type":"string_or_array_of_type"}
{"mutuallyExclusiveGroup":
	[
		...
	]
}
{"name":"varargin", "kind":"optional", "multiplicity":"append"}
</pre>
<p>The value for &#8220;kind&#8221; can be &#8220;required&#8221;, &#8220;optional&#8221;, &#8220;positional&#8221;, &#8220;flag&#8221;, &#8220;namevalue&#8221; or &#8220;platform&#8221; (and perhaps a few other lesser-used kinds):</p>
<ul>
<li>&#8220;<b>required</b>&#8221; means that the specified input is mandatory</li>
<li>&#8220;<b>optional</b>&#8221; means that it can be added or omitted</li>
<li>&#8220;<b>positional</b>&#8221; means that it&#8217;s an optional input but if it is specified then it must appear at the specified position relative to the previous (earlier) inputs</li>
<li>&#8220;<b>flag</b>&#8221; means that it&#8217;s an optional input flag, from a predefined list of one or more single-token strings. For example, in <code>regexp(s1,s2,'once')</code> the last input arg (<code>'once'</code>) is such a flag.</li>
<li>&#8220;<b>namevalue</b>&#8221; means that it follows Matlab&#8217;s standard practice of using P-V pairs (parameter name followed by its value). For example, <code>func('propName',propValue)</code></li>
<li>&#8220;<b>platform</b>&#8221; indicates that this input is only available on the specified platform(s)</li>
</ul>
<p>These &#8220;kind&#8221;s are all explained below.<br />
The value for &#8220;type&#8221; can be a string such as &#8220;char&#8221; or &#8220;numeric&#8221; or &#8220;filepath&#8221;, or a more complicated JSON array (see below).<br />
In addition to &#8220;name&#8221;, &#8220;kind&#8221; and &#8220;type&#8221;, we can also define a &#8220;default&#8221; value (e.g. <code>"default":"false"</code>) and a &#8220;display&#8221; string. While these are [currently] not used by Desktop tab-completion, they might be used by other components such as the JIT compiler or the Editor, if not today then perhaps in a future release.<br />
Note that while pure JSON format does not accept comments, Matlab&#8217;s <i>functionSignatures.json</i> does accept C++-style comments, as discovered by Heiko in a <a href="/articles/user-defined-tab-completions-take-2#comment-410166">comment below</a>. To add a comment, simply add <code>// comment text</code> at the end of any line, or <code>/* comment text */</code> anywhere within a line.</p>
<h3 id="examples">Usage examples</h3>
<p>Multiple examples of <i>functionSignatures.json</i> files can be found in subfolders of <i>%matlabroot%/toolbox/matlab</i>. For example, here&#8217;s the tab-completion definition for the <i><b>visdiff</b></i> function, which displays a visual comparison between two files, and resides in <i>%matlabroot%/toolbox/shared/comparisons/functionSignatures.json</i>:</p>
<pre lang="text">
{
"visdiff":
{
    "inputs":
    [
        {"name":"filename1", "kind":"required",   "type":"filepath"},
        {"name":"filename2", "kind":"required",   "type":"filepath"},
        {"name":"type",      "kind":"positional", "type":"choices={'text', 'binary'}"}
    ]
}
}
</pre>
<p>As can be seen in this example, the first and second inputs are expected to be a filename, whereas the third input is one of the two predefined strings &#8216;text&#8217; or &#8216;binary&#8217;. This third input has &#8220;kind&#8221;:&#8221;positional&#8221;, meaning that it is optional, but if it is provided then it must be in the 3rd position and cannot appear sooner. Moreover, if the user specifies any input argument to the &#8220;right&#8221; of a positional input, then the positional argument becomes required, not optional.<br />
Whereas a &#8220;positional&#8221; parameter has a specific position in the args list (#3 in the case of <i><b>visdiff</b></i> above), an &#8220;optional&#8221; parameter may appear anywhere in the list of inputs.<br />
Here&#8217;s a more complex example, for the built-in <i><b>regexprep</b></i> function (in <i>%matlabroot%/toolbox/matlab/strfun/functionSignatures.json</i>). This example shows how to limit the input to certain data types and how to specify optional input flags with pre-defined choices:</p>
<pre lang="text">
"regexprep":
{
	"inputs":
	[
		{"name":"str",               "kind":"required",  "type":[["char"], ["cell"], ["string"]]},
		{"name":"expression",        "kind":"required",  "type":[["char"], ["cell"], ["string"]]},
		{"name":"replace",           "kind":"required",  "type":[["char"], ["cell"], ["string"]]},
		{"name":"optMatch",          "kind":"flag",      "display":"", "type":[["char", "choices={'all','once'}"], ["numeric", "scalar"]],   "default":"'all'"},
		{"name":"optWarnings",       "kind":"flag",      "display":"", "type":["char", "choices={'nowarnings','warnings'}"],                 "default":"'nowarnings'"},
		{"name":"optCase",           "kind":"flag",      "display":"", "type":["char", "choices={'matchcase','ignorecase','preservecase'}"], "default":"'matchcase'"},
		{"name":"optEmptyMatch",     "kind":"flag",      "display":"", "type":["char", "choices={'noemptymatch','emptymatch'}"],             "default":"'noemptymatch'"},
		{"name":"optDotAll",         "kind":"flag",      "display":"", "type":["char", "choices={'dotall','dotexceptnewline'}"],             "default":"'dotall'"},
		{"name":"optStringAnchors",  "kind":"flag",      "display":"", "type":["char", "choices={'stringanchors','lineanchors'}"],           "default":"'stringanchors'"},
		{"name":"optSpacing",        "kind":"flag",      "display":"", "type":["char", "choices={'literalspacing','freespacing'}"],          "default":"'literalspacing'"}
	],
	"outputs":
	[
		{"name":"newStr", "type":[["char"], ["cell"], ["string"]]}
	]
},
</pre>
<p>Here&#8217;s an even more complex example, this time for the <i><b>codegen</b></i> function (in <i>%matlabroot%/toolbox/coder/matlabcoder/functionSignatures.json</i>, part of the Matlab Coder toolbox). This example shows how to limit the filenames to certain extensions and how to specify name-value input pairs:</p>
<pre lang="text">
"codegen":
{
	"inputs":
	[
		{"name":"compile_only",  "kind":"flag",       "type":"choices={'-c'}"},
		{"name":"config_flag",   "kind":"flag",       "type":"choices={'-config:mex','-config:lib','-config:dll','-config:exe','-config:hdl'}"},
		{"name":"debug",         "kind":"flag",       "type":"choices={'-g'}"},
		{"name":"report",        "kind":"flag",       "type":"choices={'-report'}"},
		{"name":"launchreport",  "kind":"flag",       "type":"choices={'-launchreport'}"},
		{"name":"file",          "kind":"flag",       "type":"filepath=*.m,*.mlx,*.c,*.cpp,*.h,*.o,*.obj,*.a,*.so,*.lib,*.tmf", "multiplicity":"append"},
		{"name":"-d",            "kind":"namevalue",  "type":"folderpath"},
		{"name":"-I",            "kind":"namevalue",  "type":"folderpath"},
		{"name":"-globals",      "kind":"namevalue"},
		{"name":"-o",            "kind":"namevalue",  "type":[["char"], ["filepath"]]},
		{"name":"-O",            "kind":"namevalue",  "type":"choices={'enable:inline','disable:inline','enable:blas','disable:blas','enable:openmp','disable:openmp'}"},
		{"name":"-args",         "kind":"namevalue",  "type":[["identifier=variable"], ["char"]]},
		{"name":"-config",       "kind":"namevalue",  "type":[["identifier=variable"], ["char"]]},
		{"name":"verbose",       "kind":"flag",       "type":"choices={'-v'}"},
		{"name":"singleC",       "kind":"flag",       "type":"choices={'-singleC'}"},
		{"name":"-test",         "kind":"namevalue",  "type":"identifier=function"}
	]
},
</pre>
<h3 id="types">Argument types</h3>
<p>As noted above, we use <code>"type":...</code> to specify the expected data type of each parameter. This can be a simple string such as &#8220;char&#8221;, &#8220;cellstr&#8221;, &#8220;numeric&#8221;, &#8220;table&#8221;, &#8220;categorical&#8221;, &#8220;filepath&#8221;, &#8220;folderpath&#8221;, &#8220;matlabpath&#8221;, class name, or a more complicated JSON array. For example:</p>
<ul>
<li><code>"type":["numeric","scalar"]</code></li>
<li><code>"type":["numeric","numel=3",">=4"]</code></li>
<li><code>"type":[["char"], ["cellstr"], ["numeric"], ["logical","vector"]]</code></li>
<li><code>"type":[["char", "choices={'-ascii'}"]]</code></li>
<li><code>"type":[["filepath"], ["matlabpath=*.m,*.mlx"], ["char"]]</code></li>
<li><code>"type":"identifier=variable,function,localfunction,package,classdef"</code></li>
<li><code>"type":"matlab.graphics.axis.Axes"</code></li>
<li><code>"type":"choices={'yes','no','maybe'}"</code></li>
</ul>
<p>We can even specify on-the-fly Matlab computation that returns a cell-array of values, for example a list of available fonts via <code>"type":"choices=listfonts"</code>. A more complex example is the definition of the <i><b>rmfield</b></i> function, where the possible input choices for the second input arg (highlighted) depend on the struct that is provided in the first input arg (by running the <i><b>fieldnames</b></i> function on it):</p>
<pre lang="text" highlight="6">
"rmfield":
{
	"inputs":
	[
		{"name":"s",     "kind":"required", "type":"struct"},
		{"name":"field", "kind":"required", "type":"choices=fieldnames(s)"}
	],
	"outputs":
	[
		{"name":"s", "type":"struct"}
	]
},
</pre>
<h3 id="alternatives">Alternative inputs</h3>
<p>Multiple alternative inputs can be specified in the <i>functionSignatures.json</i> file. The easiest way to do so is to simply create multiple different definitions for the same function, one beneath the other. Matlab&#8217;s tab-completion parser is smart enough to combine those definitions and proceed with the most appropriate one based on the user-entered inputs.<br />
For example, in the same Coder file above we find 6 alternative definitions. If (for example) we start typing <code>coder('-ecoder',</code> and click &lt;Tab&gt;, Matlab would automatically auto-complete the second input to &#8220;false&#8221;, and then another &lt;Tab&gt; click would set the third input to the required &#8216;-new&#8217; parameter (see highlighted lines below):</p>
<pre lang="text" highlight="34-37">
...
"coder":
{
	"inputs":
	[
		{"name":"projectname", "kind":"required", "type":"filepath=*.prj"}
	]
},
"coder":
{
	"inputs":
	[
		{"name":"-open", "kind":"namevalue", "type":"filepath=*.prj"}
	]
},
"coder":
{
	"inputs":
	[
		{"name":"-build", "kind":"namevalue", "type":"filepath=*.prj"}
	]
},
"coder":
{
	"inputs":
	[
		{"name":"-new", "kind":"namevalue", "type":[["filepath=*.prj"], ["char"]]}
	]
},
"coder":
{
	"inputs":
	[
		{"name":"ecoderFlag",  "kind":"required", "type":"choices={'-ecoder'}"},
		{"name":"ecoderValue", "kind":"required", "type":[["logical"], ["choices={'false'}"]]},
		{"name":"newFlag",     "kind":"required", "type":"choices={'-new'}"},
		{"name":"newvalue",    "kind":"required", "type":[["filepath=*.prj"], ["char"]]}
	]
},
"coder":
{
	"inputs":
	[
		{"name":"tocodeFlag",  "kind":"required", "type":"choices={'-tocode'}"},
		{"name":"tocodevalue", "kind":"required", "type":"filepath=*.prj"},
		{"mutuallyExclusiveGroup":
			[
				[],
				[
					{"name":"scriptFlag", "kind":"required", "type":"choices={'-script'}"},
					{"name":"scriptname", "kind":"required", "type":[["filepath=*.m"], ["char"]]}
				]
			]
		}
	]
}
</pre>
<p>This example also shows, in the last definition for the <i><b>coder</b></i> function, another mechanism for specifying alternative inputs, using &#8220;<b>mutuallyExclusiveGroup</b>&#8221; (aka &#8220;MEGs&#8221;). A MEG is defined using an array of options, enclosed in square brackets (<code>[]</code>). Each of the MEG options is exclusive to each of the others, meaning that we can only work with one of them and not the others. This is equivalent to duplicating the definition as we saw above, and saves us some copy-paste (in some cases a lot of copy-pastes, especially with multiple and/or nested MEGs). However, MEGs have a major drawback of reduced readability. I believe that in most cases we only have a single MEG and few input args, and in such cases it makes more sense to use repeated function defs rather than a MEG. The Matlab signature files contain numerous usage examples for either of these two mechanisms.</p>
<h3 id="platform">Platform dependencies</h3>
<p>If a specific function (or a specific signature variant) depends on the running platform, this can be specified via the &#8220;platform&#8221; directive. For example, the <i><b>winopen</b></i> function only works on Windows, but not on Linux/Mac. Its corresponding signature definition is:</p>
<pre lang="text" highlight="3">
"winopen":
{
	"platform":"win32,win64",
	"inputs":
	[
		{"name":"filename", "kind":"required", "type":"filepath"},
		{"name":"varargin", "kind":"optional", "multiplicity":"append"}
	]
}
</pre>
<p>Platform dependence could also be specified at the parameter level, not just the entire function level. For example, in the <i><b>xlsread</b></i> function (defined in <i>%matlabroot%/toolbox/matlab/iofun/functionSignatures.json</i>), we see that the usage variant <code>xlsread(filename,-1)</code> is only available on Windows (note that the numeric value is defined as <code>"&lt;=-1"</code>, not necessarily -1), and so is the &#8220;functionHandle&#8221; input (which is called <i>processFcn</i> in the documentation &#8211; for some reason that escapes me the names of many input args do not match in the documentation and functionSignature):</p>
<pre lang="text" highlight="8,14">
"xlsread":
{
	"inputs":
	[
		{"name":"filename", "kind":"required", "type":"filepath=*.xls,*.xlsx,*.xlsb,*.csv"},
		{"mutuallyExclusiveGroup":
			[
				{"name":"openExcel", "kind":"required", "display":"", "type":["numeric", "<=-1"], "platform":"win64,win32"},
				{"name":"xlRange",   "kind":"required", "type":["char", "@(x) isempty(x) || ~isempty(strfind(x, ':'))"], "default":"''"},
				[
					{"name":"sheet",          "kind":"positional", "type":[["char", "choices=matlab.internal.language.introspective.tabcompletion.xlsread_vsheet(filename)"], ["numeric", ">=1"]], "default":"1"},
					{"name":"xlRange",        "kind":"positional", "type":"char", "default":"''"},
					{"name":"basic",          "kind":"positional", "display":"", "type":["char", "choices={'basic',''}"]},
					{"name":"functionHandle", "kind":"positional", "type":"function_handle", "platform":"win64,win32"}
				]
			]
		}
	],
        ...
</pre>
<h3 id="parsing">Parsing errors</h3>
<p>The new mechanism is not very user-friendly when you get something wrong. In the best case, it issues a cryptic error message (see below), and in the worst case it simply ignores the changes and the user has no idea why the new custom tab-completion is not working as intended.<br />
The most likely causes of such problems are:</p>
<ul>
<li>The most common problem is that you placed the <i>functionSignatures.json</i> file in a different folder than the Matlab function. For example, if the myFunction() function is defined in <i>myFunction.m</i>, then the tab-completion of this function MUST be located in a <i>functionSignatures.json</i> file that resides in the same folder, not anywhere else on the Matlab path. In other words, the Matlab path is NOT relevant for tab-completion.</li>
<li>Your <i>functionSignatures.json</i> file does not follow the [extremely strict] syntax rules above, to the letter. For example, forgetting the top or final curly braces, forgetting a comma or adding an extra one, or not closing all brackets/braces properly.</li>
<li>You mistyped one or more of the input parameters, types or options.</li>
</ul>
<p>In case of a parsing error, you&#8217;d see a red error message on the Matlab console the next time that you try to use tab-completion:<br />
<code><font color="red">Error parsing JSON data; Boost reports "<unspecified file>(189): expected ',' or ']'"</font></code>.<br />
Unfortunately the error message only tells us the problematic line location within the <i>functionSignatures.json</i> file, but not the file&#8217;s location, so if we haven&#8217;t recently edited this file we&#8217;d need to find it in the relevant folder. For example:</p>
<pre lang="matlab">edit(fullfile(fileparts(which('myFunction')), 'functionSignatures.json')</pre>
<p>Moreover, when a JSON syntax error (such as the one above) occurs, the <i>entire</i> file is not parsed, not just the definition that caused the error.<br />
Another limitation of tab-completion is that it does not work while the main Matlab thread is working (e.g., during a <i><b>uiwait</b></i> or <i><b>waitfor</b></i>). This may be somewhat misleading since most editor/debugging actions do work.<br />
Arguably, this new tab-completion mechanism could be made more programmer-friendly. Perhaps this will improve in a future Matlab release.<br />
<b><u>Addendum</u></b>: MathWorks has now made this functionality supported and documented. <a href="https://www.mathworks.com/help/matlab/matlab_prog/customize-code-suggestions-and-completions.html" rel="nofollow" target="_blank">Read about it here</a>.<br />
For a related mechanism, see my article on <a href="/articles/class-object-tab-completion-and-improper-field-names" target="_blank">tab-completion for class properties and methods</a> from 2014, which is apparently still relevant and functional.</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/user-defined-tab-completions-take-2">User-defined tab completions &#8211; take 2</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/setting-desktop-tab-completions" rel="bookmark" title="Setting desktop tab completions">Setting desktop tab completions </a> <small>The Matlab desktop's Command-Window tab-completion can be customized for user-defined functions...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/enabling-user-callbacks-during-zoom-pan" rel="bookmark" title="Enabling user callbacks during zoom/pan">Enabling user callbacks during zoom/pan </a> <small>Matlab zoom, pan and rotate3d modes hijack the user's figure callbacks, but this can be overridden. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/removing-user-preferences-from-deployed-apps" rel="bookmark" title="Removing user preferences from deployed apps">Removing user preferences from deployed apps </a> <small>An unsupported MathWorks Technical Solution explains how to remove private information from deployed (compiled) matlab applications. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/creating-a-simple-udd-class" rel="bookmark" title="Creating a simple UDD class">Creating a simple UDD class </a> <small>This article explains how to create and test custom UDD packages, classes and objects...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/user-defined-tab-completions-take-2/feed</wfw:commentRss>
			<slash:comments>15</slash:comments>
		
		
			</item>
	</channel>
</rss>
